jscript: Added identifier 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 HRESULT exec_source(exec_ctx_t *ctx, parser_ctx_t *parser, source_elements_t *source, jsexcept_t *ei, VARIANT *retv)
127 {
128     script_ctx_t *script = parser->script;
129     parser_ctx_t *prev_parser;
130     VARIANT val, tmp;
131     statement_t *stat;
132     exec_ctx_t *prev_ctx;
133     return_type_t rt;
134     HRESULT hres = S_OK;
135
136     prev_ctx = script->exec_ctx;
137     script->exec_ctx = ctx;
138
139     prev_parser = ctx->parser;
140     ctx->parser = parser;
141
142     V_VT(&val) = VT_EMPTY;
143     memset(&rt, 0, sizeof(rt));
144     rt.type = RT_NORMAL;
145
146     for(stat = source->statement; stat; stat = stat->next) {
147         hres = stat_eval(ctx, stat, &rt, &tmp);
148         if(FAILED(hres))
149             break;
150
151         VariantClear(&val);
152         val = tmp;
153         if(rt.type != RT_NORMAL)
154             break;
155     }
156
157     script->exec_ctx = prev_ctx;
158     ctx->parser = prev_parser;
159
160     if(rt.type != RT_NORMAL && rt.type != RT_RETURN) {
161         FIXME("wrong rt %d\n", rt.type);
162         hres = E_FAIL;
163     }
164
165     *ei = rt.ei;
166     if(FAILED(hres)) {
167         VariantClear(&val);
168         return hres;
169     }
170
171     if(retv)
172         *retv = val;
173     else
174         VariantClear(&val);
175     return S_OK;
176 }
177
178 /* ECMA-262 3rd Edition    10.1.4 */
179 static HRESULT identifier_eval(exec_ctx_t *ctx, BSTR identifier, DWORD flags, exprval_t *ret)
180 {
181     DISPID id = 0;
182     HRESULT hres;
183
184     TRACE("%s\n", debugstr_w(identifier));
185
186     /* FIXME: scope chain */
187     /* FIXME: global */
188     /* FIXME: named items */
189
190     hres = dispex_get_id(_IDispatchEx_(ctx->parser->script->script_disp), identifier, 0, &id);
191     if(SUCCEEDED(hres)) {
192         exprval_set_idref(ret, (IDispatch*)_IDispatchEx_(ctx->parser->script->script_disp), id);
193         return S_OK;
194     }
195
196     if(flags & EXPR_NEWREF) {
197         FIXME("create ref\n");
198         return E_NOTIMPL;
199     }
200
201     WARN("Could not find identifier %s\n", debugstr_w(identifier));
202     return E_FAIL;
203 }
204
205 HRESULT block_statement_eval(exec_ctx_t *ctx, statement_t *stat, return_type_t *rt, VARIANT *ret)
206 {
207     FIXME("\n");
208     return E_NOTIMPL;
209 }
210
211 HRESULT var_statement_eval(exec_ctx_t *ctx, statement_t *stat, return_type_t *rt, VARIANT *ret)
212 {
213     FIXME("\n");
214     return E_NOTIMPL;
215 }
216
217 /* ECMA-262 3rd Edition    12.3 */
218 HRESULT empty_statement_eval(exec_ctx_t *ctx, statement_t *stat, return_type_t *rt, VARIANT *ret)
219 {
220     TRACE("\n");
221
222     V_VT(ret) = VT_EMPTY;
223     return S_OK;
224 }
225
226 /* ECMA-262 3rd Edition    12.4 */
227 HRESULT expression_statement_eval(exec_ctx_t *ctx, statement_t *_stat, return_type_t *rt, VARIANT *ret)
228 {
229     expression_statement_t *stat = (expression_statement_t*)_stat;
230     exprval_t exprval;
231     VARIANT val;
232     HRESULT hres;
233
234     TRACE("\n");
235
236     hres = expr_eval(ctx, stat->expr, EXPR_NOVAL, &rt->ei, &exprval);
237     if(FAILED(hres))
238         return hres;
239
240     hres = exprval_to_value(ctx->parser->script, &exprval, &rt->ei, &val);
241     exprval_release(&exprval);
242     if(FAILED(hres))
243         return hres;
244
245     *ret = val;
246     TRACE("= %s\n", debugstr_variant(ret));
247     return S_OK;
248 }
249
250 HRESULT if_statement_eval(exec_ctx_t *ctx, statement_t *stat, return_type_t *rt, VARIANT *ret)
251 {
252     FIXME("\n");
253     return E_NOTIMPL;
254 }
255
256 HRESULT dowhile_statement_eval(exec_ctx_t *ctx, statement_t *stat, return_type_t *rt, VARIANT *ret)
257 {
258     FIXME("\n");
259     return E_NOTIMPL;
260 }
261
262 HRESULT while_statement_eval(exec_ctx_t *ctx, statement_t *stat, return_type_t *rt, VARIANT *ret)
263 {
264     FIXME("\n");
265     return E_NOTIMPL;
266 }
267
268 HRESULT for_statement_eval(exec_ctx_t *ctx, statement_t *stat, return_type_t *rt, VARIANT *ret)
269 {
270     FIXME("\n");
271     return E_NOTIMPL;
272 }
273
274 HRESULT forin_statement_eval(exec_ctx_t *ctx, statement_t *stat, return_type_t *rt, VARIANT *ret)
275 {
276     FIXME("\n");
277     return E_NOTIMPL;
278 }
279
280 HRESULT continue_statement_eval(exec_ctx_t *ctx, statement_t *stat, return_type_t *rt, VARIANT *ret)
281 {
282     FIXME("\n");
283     return E_NOTIMPL;
284 }
285
286 HRESULT break_statement_eval(exec_ctx_t *ctx, statement_t *stat, return_type_t *rt, VARIANT *ret)
287 {
288     FIXME("\n");
289     return E_NOTIMPL;
290 }
291
292 HRESULT return_statement_eval(exec_ctx_t *ctx, statement_t *stat, return_type_t *rt, VARIANT *ret)
293 {
294     FIXME("\n");
295     return E_NOTIMPL;
296 }
297
298 HRESULT with_statement_eval(exec_ctx_t *ctx, statement_t *stat, return_type_t *rt, VARIANT *ret)
299 {
300     FIXME("\n");
301     return E_NOTIMPL;
302 }
303
304 HRESULT labelled_statement_eval(exec_ctx_t *ctx, statement_t *stat, return_type_t *rt, VARIANT *ret)
305 {
306     FIXME("\n");
307     return E_NOTIMPL;
308 }
309
310 HRESULT switch_statement_eval(exec_ctx_t *ctx, statement_t *stat, return_type_t *rt, VARIANT *ret)
311 {
312     FIXME("\n");
313     return E_NOTIMPL;
314 }
315
316 HRESULT throw_statement_eval(exec_ctx_t *ctx, statement_t *stat, return_type_t *rt, VARIANT *ret)
317 {
318     FIXME("\n");
319     return E_NOTIMPL;
320 }
321
322 HRESULT try_statement_eval(exec_ctx_t *ctx, statement_t *stat, return_type_t *rt, VARIANT *ret)
323 {
324     FIXME("\n");
325     return E_NOTIMPL;
326 }
327
328 HRESULT function_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
329 {
330     FIXME("\n");
331     return E_NOTIMPL;
332 }
333
334 HRESULT conditional_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
335 {
336     FIXME("\n");
337     return E_NOTIMPL;
338 }
339
340 HRESULT array_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
341 {
342     FIXME("\n");
343     return E_NOTIMPL;
344 }
345
346 HRESULT member_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
347 {
348     FIXME("\n");
349     return E_NOTIMPL;
350 }
351
352 HRESULT member_new_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
353 {
354     FIXME("\n");
355     return E_NOTIMPL;
356 }
357
358 HRESULT call_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
359 {
360     FIXME("\n");
361     return E_NOTIMPL;
362 }
363
364 HRESULT this_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
365 {
366     FIXME("\n");
367     return E_NOTIMPL;
368 }
369
370 /* ECMA-262 3rd Edition    10.1.4 */
371 HRESULT identifier_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
372 {
373     identifier_expression_t *expr = (identifier_expression_t*)_expr;
374     BSTR identifier;
375     HRESULT hres;
376
377     TRACE("\n");
378
379     identifier = SysAllocString(expr->identifier);
380     if(!identifier)
381         return E_OUTOFMEMORY;
382
383     hres = identifier_eval(ctx, identifier, flags, ret);
384
385     SysFreeString(identifier);
386     return hres;
387 }
388
389 HRESULT literal_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
390 {
391     FIXME("\n");
392     return E_NOTIMPL;
393 }
394
395 HRESULT array_literal_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
396 {
397     FIXME("\n");
398     return E_NOTIMPL;
399 }
400
401 HRESULT property_value_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
402 {
403     FIXME("\n");
404     return E_NOTIMPL;
405 }
406
407 HRESULT comma_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
408 {
409     FIXME("\n");
410     return E_NOTIMPL;
411 }
412
413 HRESULT logical_or_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
414 {
415     FIXME("\n");
416     return E_NOTIMPL;
417 }
418
419 HRESULT logical_and_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
420 {
421     FIXME("\n");
422     return E_NOTIMPL;
423 }
424
425 HRESULT binary_or_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
426 {
427     FIXME("\n");
428     return E_NOTIMPL;
429 }
430
431 HRESULT binary_xor_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
432 {
433     FIXME("\n");
434     return E_NOTIMPL;
435 }
436
437 HRESULT binary_and_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
438 {
439     FIXME("\n");
440     return E_NOTIMPL;
441 }
442
443 HRESULT instanceof_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
444 {
445     FIXME("\n");
446     return E_NOTIMPL;
447 }
448
449 HRESULT in_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
450 {
451     FIXME("\n");
452     return E_NOTIMPL;
453 }
454
455 HRESULT add_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
456 {
457     FIXME("\n");
458     return E_NOTIMPL;
459 }
460
461 HRESULT sub_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
462 {
463     FIXME("\n");
464     return E_NOTIMPL;
465 }
466
467 HRESULT mul_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
468 {
469     FIXME("\n");
470     return E_NOTIMPL;
471 }
472
473 HRESULT div_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
474 {
475     FIXME("\n");
476     return E_NOTIMPL;
477 }
478
479 HRESULT mod_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
480 {
481     FIXME("\n");
482     return E_NOTIMPL;
483 }
484
485 HRESULT delete_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
486 {
487     FIXME("\n");
488     return E_NOTIMPL;
489 }
490
491 HRESULT void_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
492 {
493     FIXME("\n");
494     return E_NOTIMPL;
495 }
496
497 HRESULT typeof_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
498 {
499     FIXME("\n");
500     return E_NOTIMPL;
501 }
502
503 HRESULT minus_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
504 {
505     FIXME("\n");
506     return E_NOTIMPL;
507 }
508
509 HRESULT plus_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
510 {
511     FIXME("\n");
512     return E_NOTIMPL;
513 }
514
515 HRESULT post_increment_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
516 {
517     FIXME("\n");
518     return E_NOTIMPL;
519 }
520
521 HRESULT post_decrement_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
522 {
523     FIXME("\n");
524     return E_NOTIMPL;
525 }
526
527 HRESULT pre_increment_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
528 {
529     FIXME("\n");
530     return E_NOTIMPL;
531 }
532
533 HRESULT pre_decrement_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
534 {
535     FIXME("\n");
536     return E_NOTIMPL;
537 }
538
539 HRESULT new_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
540 {
541     FIXME("\n");
542     return E_NOTIMPL;
543 }
544
545 HRESULT equal_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
546 {
547     FIXME("\n");
548     return E_NOTIMPL;
549 }
550
551 HRESULT equal2_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
552 {
553     FIXME("\n");
554     return E_NOTIMPL;
555 }
556
557 HRESULT not_equal_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
558 {
559
560     FIXME("\n");
561     return E_NOTIMPL;
562 }
563
564 HRESULT not_equal2_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
565 {
566     FIXME("\n");
567     return E_NOTIMPL;
568 }
569
570 HRESULT less_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
571 {
572     FIXME("\n");
573     return E_NOTIMPL;
574 }
575
576 HRESULT lesseq_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
577 {
578     FIXME("\n");
579     return E_NOTIMPL;
580 }
581
582 HRESULT greater_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
583 {
584     FIXME("\n");
585     return E_NOTIMPL;
586 }
587
588 HRESULT greatereq_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
589 {
590     FIXME("\n");
591     return E_NOTIMPL;
592 }
593
594 HRESULT binary_negation_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
595 {
596     FIXME("\n");
597     return E_NOTIMPL;
598 }
599
600 HRESULT logical_negation_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
601 {
602     FIXME("\n");
603     return E_NOTIMPL;
604 }
605
606 HRESULT left_shift_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
607 {
608     FIXME("\n");
609     return E_NOTIMPL;
610 }
611
612 HRESULT right_shift_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
613 {
614     FIXME("\n");
615     return E_NOTIMPL;
616 }
617
618 HRESULT right2_shift_expression_eval(exec_ctx_t *ctx, expression_t *_expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
619 {
620     FIXME("\n");
621     return E_NOTIMPL;
622 }
623
624 HRESULT assign_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
625 {
626     FIXME("\n");
627     return E_NOTIMPL;
628 }
629
630 HRESULT assign_lshift_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
631 {
632     FIXME("\n");
633     return E_NOTIMPL;
634 }
635
636 HRESULT assign_rshift_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
637 {
638     FIXME("\n");
639     return E_NOTIMPL;
640 }
641
642 HRESULT assign_rrshift_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
643 {
644     FIXME("\n");
645     return E_NOTIMPL;
646 }
647
648 HRESULT assign_add_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
649 {
650     FIXME("\n");
651     return E_NOTIMPL;
652 }
653
654 HRESULT assign_sub_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
655 {
656     FIXME("\n");
657     return E_NOTIMPL;
658 }
659
660 HRESULT assign_mul_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
661 {
662     FIXME("\n");
663     return E_NOTIMPL;
664 }
665
666 HRESULT assign_div_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
667 {
668     FIXME("\n");
669     return E_NOTIMPL;
670 }
671
672 HRESULT assign_mod_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
673 {
674     FIXME("\n");
675     return E_NOTIMPL;
676 }
677
678 HRESULT assign_and_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
679 {
680     FIXME("\n");
681     return E_NOTIMPL;
682 }
683
684 HRESULT assign_or_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
685 {
686     FIXME("\n");
687     return E_NOTIMPL;
688 }
689
690 HRESULT assign_xor_expression_eval(exec_ctx_t *ctx, expression_t *expr, DWORD flags, jsexcept_t *ei, exprval_t *ret)
691 {
692     FIXME("\n");
693     return E_NOTIMPL;
694 }