jscript: Added literal expression implementation.
[wine] / dlls / jscript / engine.c
1 /*
2  * Copyright 2008 Jacek Caban for CodeWeavers
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
17  */
18
19 #include "jscript.h"
20 #include "engine.h"
21
22 #include "wine/debug.h"
23
24 WINE_DEFAULT_DEBUG_CHANNEL(jscript);
25
26 #define EXPR_NOVAL   0x0001
27 #define EXPR_NEWREF  0x0002
28 #define EXPR_STRREF  0x0004
29
30 static inline HRESULT stat_eval(exec_ctx_t *ctx, statement_t *stat, return_type_t *rt, VARIANT *ret)
31 {
32     return stat->eval(ctx, stat, rt, ret);
33 }
34
35 static inline HRESULT expr_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
36 {
37     return _expr->eval(ctx, _expr, flags, ei, ret);
38 }
39
40 static void exprval_release(exprval_t *val)
41 {
42     switch(val->type) {
43     case EXPRVAL_VARIANT:
44         VariantClear(&val->u.var);
45         return;
46     case EXPRVAL_IDREF:
47         if(val->u.idref.disp)
48             IDispatch_Release(val->u.idref.disp);
49         return;
50     case EXPRVAL_NAMEREF:
51         if(val->u.nameref.disp)
52             IDispatch_Release(val->u.nameref.disp);
53         SysFreeString(val->u.nameref.name);
54     }
55 }
56
57 /* ECMA-262 3rd Edition    8.7.1 */
58 static HRESULT exprval_value(script_ctx_t *ctx, exprval_t *val, jsexcept_t *ei, VARIANT *ret)
59 {
60     V_VT(ret) = VT_EMPTY;
61
62     switch(val->type) {
63     case EXPRVAL_VARIANT:
64         return VariantCopy(ret, &val->u.var);
65     case EXPRVAL_IDREF:
66         if(!val->u.idref.disp) {
67             FIXME("throw ReferenceError\n");
68             return E_FAIL;
69         }
70
71         return disp_propget(val->u.idref.disp, val->u.idref.id, ctx->lcid, ret, ei, NULL/*FIXME*/);
72     default:
73         ERR("type %d\n", val->type);
74         return E_FAIL;
75     }
76 }
77
78 static HRESULT exprval_to_value(script_ctx_t *ctx, exprval_t *val, jsexcept_t *ei, VARIANT *ret)
79 {
80     if(val->type == EXPRVAL_VARIANT) {
81         *ret = val->u.var;
82         V_VT(&val->u.var) = VT_EMPTY;
83         return S_OK;
84     }
85
86     return exprval_value(ctx, val, ei, ret);
87 }
88
89 static void exprval_set_idref(exprval_t *val, IDispatch *disp, DISPID id)
90 {
91     val->type = EXPRVAL_IDREF;
92     val->u.idref.disp = disp;
93     val->u.idref.id = id;
94
95     if(disp)
96         IDispatch_AddRef(disp);
97 }
98
99 HRESULT create_exec_ctx(exec_ctx_t **ret)
100 {
101     exec_ctx_t *ctx;
102
103     ctx = heap_alloc_zero(sizeof(exec_ctx_t));
104     if(!ctx)
105         return E_OUTOFMEMORY;
106
107     *ret = ctx;
108     return S_OK;
109 }
110
111 void exec_release(exec_ctx_t *ctx)
112 {
113     if(--ctx->ref)
114         return;
115
116     heap_free(ctx);
117 }
118
119 static HRESULT dispex_get_id(IDispatchEx *dispex, BSTR name, DWORD flags, DISPID *id)
120 {
121     *id = 0;
122
123     return IDispatchEx_GetDispID(dispex, name, flags|fdexNameCaseSensitive, id);
124 }
125
126 static HRESULT disp_get_id(IDispatch *disp, BSTR name, DWORD flags, DISPID *id)
127 {
128     IDispatchEx *dispex;
129     HRESULT hres;
130
131     hres = IDispatch_QueryInterface(disp, &IID_IDispatchEx, (void**)&dispex);
132     if(FAILED(hres)) {
133         TRACE("unsing IDispatch\n");
134
135         *id = 0;
136         return IDispatch_GetIDsOfNames(disp, &IID_NULL, &name, 1, 0, id);
137     }
138
139     hres = dispex_get_id(dispex, name, flags, id);
140     IDispatchEx_Release(dispex);
141     return hres;
142 }
143
144 /* ECMA-262 3rd Edition    8.7.2 */
145 static HRESULT put_value(script_ctx_t *ctx, exprval_t *ref, VARIANT *v, jsexcept_t *ei)
146 {
147     if(ref->type != EXPRVAL_IDREF) {
148         FIXME("throw ReferemceError\n");
149         return E_FAIL;
150     }
151
152     return disp_propput(ref->u.idref.disp, ref->u.idref.id, ctx->lcid, v, ei, NULL/*FIXME*/);
153 }
154
155 static HRESULT literal_to_var(literal_t *literal, VARIANT *v)
156 {
157     V_VT(v) = literal->vt;
158
159     switch(V_VT(v)) {
160     case VT_EMPTY:
161     case VT_NULL:
162         break;
163     case VT_I4:
164         V_I4(v) = literal->u.lval;
165         break;
166     case VT_R8:
167         V_R8(v) = literal->u.dval;
168         break;
169     case VT_BSTR:
170         V_BSTR(v) = SysAllocString(literal->u.wstr);
171         break;
172     case VT_BOOL:
173         V_BOOL(v) = literal->u.bval;
174         break;
175     case VT_DISPATCH:
176         IDispatch_AddRef(literal->u.disp);
177         V_DISPATCH(v) = literal->u.disp;
178         break;
179     default:
180         ERR("wrong type %d\n", V_VT(v));
181         return E_NOTIMPL;
182     }
183
184     return S_OK;
185 }
186
187 HRESULT exec_source(exec_ctx_t *ctx, parser_ctx_t *parser, source_elements_t *source, jsexcept_t *ei, VARIANT *retv)
188 {
189     script_ctx_t *script = parser->script;
190     parser_ctx_t *prev_parser;
191     VARIANT val, tmp;
192     statement_t *stat;
193     exec_ctx_t *prev_ctx;
194     return_type_t rt;
195     HRESULT hres = S_OK;
196
197     prev_ctx = script->exec_ctx;
198     script->exec_ctx = ctx;
199
200     prev_parser = ctx->parser;
201     ctx->parser = parser;
202
203     V_VT(&val) = VT_EMPTY;
204     memset(&rt, 0, sizeof(rt));
205     rt.type = RT_NORMAL;
206
207     for(stat = source->statement; stat; stat = stat->next) {
208         hres = stat_eval(ctx, stat, &rt, &tmp);
209         if(FAILED(hres))
210             break;
211
212         VariantClear(&val);
213         val = tmp;
214         if(rt.type != RT_NORMAL)
215             break;
216     }
217
218     script->exec_ctx = prev_ctx;
219     ctx->parser = prev_parser;
220
221     if(rt.type != RT_NORMAL && rt.type != RT_RETURN) {
222         FIXME("wrong rt %d\n", rt.type);
223         hres = E_FAIL;
224     }
225
226     *ei = rt.ei;
227     if(FAILED(hres)) {
228         VariantClear(&val);
229         return hres;
230     }
231
232     if(retv)
233         *retv = val;
234     else
235         VariantClear(&val);
236     return S_OK;
237 }
238
239 /* ECMA-262 3rd Edition    10.1.4 */
240 static HRESULT identifier_eval(exec_ctx_t *ctx, BSTR identifier, DWORD flags, exprval_t *ret)
241 {
242     named_item_t *item;
243     DISPID id = 0;
244     HRESULT hres;
245
246     TRACE("%s\n", debugstr_w(identifier));
247
248     /* FIXME: scope chain */
249
250     hres = dispex_get_id(_IDispatchEx_(ctx->parser->script->global), identifier, 0, &id);
251     if(SUCCEEDED(hres)) {
252         exprval_set_idref(ret, (IDispatch*)_IDispatchEx_(ctx->parser->script->global), id);
253         return S_OK;
254     }
255
256     for(item = ctx->parser->script->named_items; item; item = item->next) {
257         hres = disp_get_id(item->disp, identifier, 0, &id);
258         if(SUCCEEDED(hres))
259             break;
260     }
261
262     if(item) {
263         exprval_set_idref(ret, (IDispatch*)item->disp, id);
264         return S_OK;
265     }
266
267     hres = dispex_get_id(_IDispatchEx_(ctx->parser->script->script_disp), identifier, 0, &id);
268     if(SUCCEEDED(hres)) {
269         exprval_set_idref(ret, (IDispatch*)_IDispatchEx_(ctx->parser->script->script_disp), id);
270         return S_OK;
271     }
272
273     if(flags & EXPR_NEWREF) {
274         FIXME("create ref\n");
275         return E_NOTIMPL;
276     }
277
278     WARN("Could not find identifier %s\n", debugstr_w(identifier));
279     return E_FAIL;
280 }
281
282 HRESULT block_statement_eval(exec_ctx_t *ctx, statement_t *stat, return_type_t *rt, VARIANT *ret)
283 {
284     FIXME("\n");
285     return E_NOTIMPL;
286 }
287
288 HRESULT var_statement_eval(exec_ctx_t *ctx, statement_t *stat, return_type_t *rt, VARIANT *ret)
289 {
290     FIXME("\n");
291     return E_NOTIMPL;
292 }
293
294 /* ECMA-262 3rd Edition    12.3 */
295 HRESULT empty_statement_eval(exec_ctx_t *ctx, statement_t *stat, return_type_t *rt, VARIANT *ret)
296 {
297     TRACE("\n");
298
299     V_VT(ret) = VT_EMPTY;
300     return S_OK;
301 }
302
303 /* ECMA-262 3rd Edition    12.4 */
304 HRESULT expression_statement_eval(exec_ctx_t *ctx, statement_t *_stat, return_type_t *rt, VARIANT *ret)
305 {
306     expression_statement_t *stat = (expression_statement_t*)_stat;
307     exprval_t exprval;
308     VARIANT val;
309     HRESULT hres;
310
311     TRACE("\n");
312
313     hres = expr_eval(ctx, stat->expr, EXPR_NOVAL, &rt->ei, &exprval);
314     if(FAILED(hres))
315         return hres;
316
317     hres = exprval_to_value(ctx->parser->script, &exprval, &rt->ei, &val);
318     exprval_release(&exprval);
319     if(FAILED(hres))
320         return hres;
321
322     *ret = val;
323     TRACE("= %s\n", debugstr_variant(ret));
324     return S_OK;
325 }
326
327 HRESULT if_statement_eval(exec_ctx_t *ctx, statement_t *stat, return_type_t *rt, VARIANT *ret)
328 {
329     FIXME("\n");
330     return E_NOTIMPL;
331 }
332
333 HRESULT dowhile_statement_eval(exec_ctx_t *ctx, statement_t *stat, return_type_t *rt, VARIANT *ret)
334 {
335     FIXME("\n");
336     return E_NOTIMPL;
337 }
338
339 HRESULT while_statement_eval(exec_ctx_t *ctx, statement_t *stat, return_type_t *rt, VARIANT *ret)
340 {
341     FIXME("\n");
342     return E_NOTIMPL;
343 }
344
345 HRESULT for_statement_eval(exec_ctx_t *ctx, statement_t *stat, return_type_t *rt, VARIANT *ret)
346 {
347     FIXME("\n");
348     return E_NOTIMPL;
349 }
350
351 HRESULT forin_statement_eval(exec_ctx_t *ctx, statement_t *stat, return_type_t *rt, VARIANT *ret)
352 {
353     FIXME("\n");
354     return E_NOTIMPL;
355 }
356
357 HRESULT continue_statement_eval(exec_ctx_t *ctx, statement_t *stat, return_type_t *rt, VARIANT *ret)
358 {
359     FIXME("\n");
360     return E_NOTIMPL;
361 }
362
363 HRESULT break_statement_eval(exec_ctx_t *ctx, statement_t *stat, return_type_t *rt, VARIANT *ret)
364 {
365     FIXME("\n");
366     return E_NOTIMPL;
367 }
368
369 HRESULT return_statement_eval(exec_ctx_t *ctx, statement_t *stat, return_type_t *rt, VARIANT *ret)
370 {
371     FIXME("\n");
372     return E_NOTIMPL;
373 }
374
375 HRESULT with_statement_eval(exec_ctx_t *ctx, statement_t *stat, return_type_t *rt, VARIANT *ret)
376 {
377     FIXME("\n");
378     return E_NOTIMPL;
379 }
380
381 HRESULT labelled_statement_eval(exec_ctx_t *ctx, statement_t *stat, return_type_t *rt, VARIANT *ret)
382 {
383     FIXME("\n");
384     return E_NOTIMPL;
385 }
386
387 HRESULT switch_statement_eval(exec_ctx_t *ctx, statement_t *stat, return_type_t *rt, VARIANT *ret)
388 {
389     FIXME("\n");
390     return E_NOTIMPL;
391 }
392
393 HRESULT throw_statement_eval(exec_ctx_t *ctx, statement_t *stat, return_type_t *rt, VARIANT *ret)
394 {
395     FIXME("\n");
396     return E_NOTIMPL;
397 }
398
399 HRESULT try_statement_eval(exec_ctx_t *ctx, statement_t *stat, return_type_t *rt, VARIANT *ret)
400 {
401     FIXME("\n");
402     return E_NOTIMPL;
403 }
404
405 HRESULT function_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
406 {
407     FIXME("\n");
408     return E_NOTIMPL;
409 }
410
411 HRESULT conditional_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
412 {
413     FIXME("\n");
414     return E_NOTIMPL;
415 }
416
417 HRESULT array_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
418 {
419     FIXME("\n");
420     return E_NOTIMPL;
421 }
422
423 HRESULT member_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
424 {
425     FIXME("\n");
426     return E_NOTIMPL;
427 }
428
429 HRESULT member_new_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
430 {
431     FIXME("\n");
432     return E_NOTIMPL;
433 }
434
435 HRESULT call_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
436 {
437     FIXME("\n");
438     return E_NOTIMPL;
439 }
440
441 HRESULT this_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
442 {
443     FIXME("\n");
444     return E_NOTIMPL;
445 }
446
447 /* ECMA-262 3rd Edition    10.1.4 */
448 HRESULT identifier_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
449 {
450     identifier_expression_t *expr = (identifier_expression_t*)_expr;
451     BSTR identifier;
452     HRESULT hres;
453
454     TRACE("\n");
455
456     identifier = SysAllocString(expr->identifier);
457     if(!identifier)
458         return E_OUTOFMEMORY;
459
460     hres = identifier_eval(ctx, identifier, flags, ret);
461
462     SysFreeString(identifier);
463     return hres;
464 }
465
466 /* ECMA-262 3rd Edition    7.8 */
467 HRESULT literal_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
468 {
469     literal_expression_t *expr = (literal_expression_t*)_expr;
470     VARIANT var;
471     HRESULT hres;
472
473     TRACE("\n");
474
475     hres = literal_to_var(expr->literal, &var);
476     if(FAILED(hres))
477         return hres;
478
479     ret->type = EXPRVAL_VARIANT;
480     ret->u.var = var;
481     return S_OK;
482 }
483
484 HRESULT array_literal_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
485 {
486     FIXME("\n");
487     return E_NOTIMPL;
488 }
489
490 HRESULT property_value_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
491 {
492     FIXME("\n");
493     return E_NOTIMPL;
494 }
495
496 HRESULT comma_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
497 {
498     FIXME("\n");
499     return E_NOTIMPL;
500 }
501
502 HRESULT logical_or_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
503 {
504     FIXME("\n");
505     return E_NOTIMPL;
506 }
507
508 HRESULT logical_and_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
509 {
510     FIXME("\n");
511     return E_NOTIMPL;
512 }
513
514 HRESULT binary_or_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
515 {
516     FIXME("\n");
517     return E_NOTIMPL;
518 }
519
520 HRESULT binary_xor_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
521 {
522     FIXME("\n");
523     return E_NOTIMPL;
524 }
525
526 HRESULT binary_and_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
527 {
528     FIXME("\n");
529     return E_NOTIMPL;
530 }
531
532 HRESULT instanceof_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
533 {
534     FIXME("\n");
535     return E_NOTIMPL;
536 }
537
538 HRESULT in_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
539 {
540     FIXME("\n");
541     return E_NOTIMPL;
542 }
543
544 HRESULT add_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
545 {
546     FIXME("\n");
547     return E_NOTIMPL;
548 }
549
550 HRESULT sub_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
551 {
552     FIXME("\n");
553     return E_NOTIMPL;
554 }
555
556 HRESULT mul_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
557 {
558     FIXME("\n");
559     return E_NOTIMPL;
560 }
561
562 HRESULT div_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
563 {
564     FIXME("\n");
565     return E_NOTIMPL;
566 }
567
568 HRESULT mod_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
569 {
570     FIXME("\n");
571     return E_NOTIMPL;
572 }
573
574 HRESULT delete_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
575 {
576     FIXME("\n");
577     return E_NOTIMPL;
578 }
579
580 HRESULT void_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
581 {
582     FIXME("\n");
583     return E_NOTIMPL;
584 }
585
586 HRESULT typeof_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
587 {
588     FIXME("\n");
589     return E_NOTIMPL;
590 }
591
592 HRESULT minus_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
593 {
594     FIXME("\n");
595     return E_NOTIMPL;
596 }
597
598 HRESULT plus_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
599 {
600     FIXME("\n");
601     return E_NOTIMPL;
602 }
603
604 HRESULT post_increment_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
605 {
606     FIXME("\n");
607     return E_NOTIMPL;
608 }
609
610 HRESULT post_decrement_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
611 {
612     FIXME("\n");
613     return E_NOTIMPL;
614 }
615
616 HRESULT pre_increment_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
617 {
618     FIXME("\n");
619     return E_NOTIMPL;
620 }
621
622 HRESULT pre_decrement_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
623 {
624     FIXME("\n");
625     return E_NOTIMPL;
626 }
627
628 HRESULT new_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
629 {
630     FIXME("\n");
631     return E_NOTIMPL;
632 }
633
634 HRESULT equal_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
635 {
636     FIXME("\n");
637     return E_NOTIMPL;
638 }
639
640 HRESULT equal2_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
641 {
642     FIXME("\n");
643     return E_NOTIMPL;
644 }
645
646 HRESULT not_equal_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
647 {
648
649     FIXME("\n");
650     return E_NOTIMPL;
651 }
652
653 HRESULT not_equal2_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
654 {
655     FIXME("\n");
656     return E_NOTIMPL;
657 }
658
659 HRESULT less_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
660 {
661     FIXME("\n");
662     return E_NOTIMPL;
663 }
664
665 HRESULT lesseq_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
666 {
667     FIXME("\n");
668     return E_NOTIMPL;
669 }
670
671 HRESULT greater_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
672 {
673     FIXME("\n");
674     return E_NOTIMPL;
675 }
676
677 HRESULT greatereq_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
678 {
679     FIXME("\n");
680     return E_NOTIMPL;
681 }
682
683 HRESULT binary_negation_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
684 {
685     FIXME("\n");
686     return E_NOTIMPL;
687 }
688
689 HRESULT logical_negation_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
690 {
691     FIXME("\n");
692     return E_NOTIMPL;
693 }
694
695 HRESULT left_shift_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
696 {
697     FIXME("\n");
698     return E_NOTIMPL;
699 }
700
701 HRESULT right_shift_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
702 {
703     FIXME("\n");
704     return E_NOTIMPL;
705 }
706
707 HRESULT right2_shift_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
708 {
709     FIXME("\n");
710     return E_NOTIMPL;
711 }
712
713 /* ECMA-262 3rd Edition    11.13.1 */
714 HRESULT assign_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
715 {
716     binary_expression_t *expr = (binary_expression_t*)_expr;
717     exprval_t exprval, exprvalr;
718     VARIANT rval;
719     HRESULT hres;
720
721     TRACE("\n");
722
723     hres = expr_eval(ctx, expr->expression1, EXPR_NEWREF, ei, &exprval);
724     if(FAILED(hres))
725         return hres;
726
727     hres = expr_eval(ctx, expr->expression2, 0, ei, &exprvalr);
728     if(SUCCEEDED(hres)) {
729         hres = exprval_to_value(ctx->parser->script, &exprvalr, ei, &rval);
730         exprval_release(&exprvalr);
731     }
732
733     if(SUCCEEDED(hres))
734         hres = put_value(ctx->parser->script, &exprval, &rval, ei);
735
736     exprval_release(&exprval);
737     if(FAILED(hres)) {
738         VariantClear(&rval);
739         return hres;
740     }
741
742     ret->type = EXPRVAL_VARIANT;
743     ret->u.var = rval;
744     return S_OK;
745 }
746
747 HRESULT assign_lshift_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
748 {
749     FIXME("\n");
750     return E_NOTIMPL;
751 }
752
753 HRESULT assign_rshift_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
754 {
755     FIXME("\n");
756     return E_NOTIMPL;
757 }
758
759 HRESULT assign_rrshift_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
760 {
761     FIXME("\n");
762     return E_NOTIMPL;
763 }
764
765 HRESULT assign_add_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
766 {
767     FIXME("\n");
768     return E_NOTIMPL;
769 }
770
771 HRESULT assign_sub_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
772 {
773     FIXME("\n");
774     return E_NOTIMPL;
775 }
776
777 HRESULT assign_mul_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
778 {
779     FIXME("\n");
780     return E_NOTIMPL;
781 }
782
783 HRESULT assign_div_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
784 {
785     FIXME("\n");
786     return E_NOTIMPL;
787 }
788
789 HRESULT assign_mod_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
790 {
791     FIXME("\n");
792     return E_NOTIMPL;
793 }
794
795 HRESULT assign_and_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
796 {
797     FIXME("\n");
798     return E_NOTIMPL;
799 }
800
801 HRESULT assign_or_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
802 {
803     FIXME("\n");
804     return E_NOTIMPL;
805 }
806
807 HRESULT assign_xor_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
808 {
809     FIXME("\n");
810     return E_NOTIMPL;
811 }