1 /*----------------------------------------------------------------------------
2 ChucK Concurrent, On-the-fly Audio Programming Language
3 Compiler and Virtual Machine
5 Copyright (c) 2004 Ge Wang and Perry R. Cook. All rights reserved.
6 http://chuck.cs.princeton.edu/
7 http://soundlab.cs.princeton.edu/
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 2 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program; if not, write to the Free Software
21 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
23 -----------------------------------------------------------------------------*/
25 //-----------------------------------------------------------------------------
26 // file: chuck_emit.cpp
29 // author: Ge Wang (gewang@cs.princeton.edu)
30 // Perry R. Cook (prc@cs.princeton.edu)
32 // Autumn 2003 updated
33 //-----------------------------------------------------------------------------
38 #include "chuck_emit.h"
39 #include "chuck_frame.h"
40 #include "chuck_instr.h"
41 #include "chuck_bbq.h"
43 #include "chuck_errmsg.h"
48 //-----------------------------------------------------------------------------
49 // name: class Chuck_Code
51 //-----------------------------------------------------------------------------
55 vector
<Chuck_Instr
*> code
;
58 unsigned int stack_depth
;
60 Chuck_Code( c_str scope_name
)
63 frame
= F_new_frame( Temp_named_label( scope_name
) );
69 // TODO: free the frame
76 //-----------------------------------------------------------------------------
77 // name: struct Dur_Node
79 //-----------------------------------------------------------------------------
91 //-----------------------------------------------------------------------------
92 // name: struct Func_Link
94 //-----------------------------------------------------------------------------
98 Chuck_Instr_Reg_Push_Imm
* op
;
102 S_table g_func2code
= NULL
;
103 vector
<Func_Link
*> g_func_links
;
108 //-----------------------------------------------------------------------------
109 // name: struct Chuck_Emmission
111 //-----------------------------------------------------------------------------
112 struct Chuck_Emmission
116 vector
<Chuck_Code
*> functions
;
118 S_table dur2num_samps
;
121 unsigned int is_global
;
123 unsigned int chuck_count
;
124 vector
<Chuck_Instr_Branch_Op
*> returns
;
125 vector
<Chuck_Instr_Unary_Op
*> addr_map
;
129 a_Func_Def nspc_func
;
130 vector
<Chuck_Instr_Unary_Op
*> ops
;
132 Chuck_Emmission( t_Env e
)
136 var2offset
= S_empty();
137 dur2num_samps
= S_empty();
148 void push_op( Chuck_Instr_Unary_Op
* a
)
153 Chuck_Instr_Unary_Op
* get_op()
155 if( ops
.size() ) return ops
[ops
.size()-1];
161 if( ops
.size() ) ops
.pop_back();
176 // while( get_op() ) pop_op();
179 uint
append( Chuck_Instr
* instr
)
183 global
->code
.push_back( instr
);
184 return (uint
)global
->code
.size() - 1;
188 local
->code
.push_back( instr
);
189 return (uint
)local
->code
.size() - 1;
193 Chuck_Instr
* remove_last( )
197 if( global
->code
.size() == 0 ) return NULL
;
198 Chuck_Instr
* instr
= *global
->code
.end();
199 global
->code
.pop_back();
204 if( local
->code
.size() == 0 ) return NULL
;
205 Chuck_Instr
* instr
= *local
->code
.end();
206 local
->code
.pop_back();
214 return (uint
)global
->code
.size();
216 return (uint
)local
->code
.size();
219 void alloc_dur( S_Symbol var
, t_CKDUR samp
)
221 S_enter( dur2num_samps
, var
, new Dur_Node( samp
) );
224 uint
find_dur( S_Symbol var
, t_CKDUR
* dur
)
226 Dur_Node
* n
= (Dur_Node
*)S_look( dur2num_samps
, var
);
234 unsigned int alloc_local( S_Symbol var
, t_Type type
)
236 // allocate offset in the frame
239 a
= F_alloc_local( global
->frame
, type
->size
, is_global
);
241 a
= F_alloc_local( local
->frame
, type
->size
, is_global
);
243 unsigned int offset
= F_offset( a
);
246 S_enter( var2offset
, var
, a
);
251 int find_offset( S_Symbol var
, t_CKBOOL
* isglobal
= NULL
, t_CKUINT
* size
= NULL
)
253 F_Access a
= (F_Access
)S_look( var2offset
, var
);
257 *isglobal
= a
->global
;
264 unsigned int stack_depth()
267 return F_stack_depth( global
->frame
);
269 return F_stack_depth( local
->frame
);
272 void push( c_str scope_name
= NULL
)
274 S_beginScope( var2offset
);
275 if( this->is_global
)
276 F_begin_scope( global
->frame
);
278 F_begin_scope( local
->frame
);
286 EM_error2( 0, "(emit): internal error - too many pop()!" );
290 S_endScope( var2offset
);
292 F_end_scope( global
->frame
);
294 F_end_scope( local
->frame
);
302 //-----------------------------------------------------------------------------
303 // name: emit_to_code()
304 // desc: emit to vm code
305 //-----------------------------------------------------------------------------
306 Chuck_VM_Code
* emit_to_code( Chuck_Emmission
* emit
, t_CKBOOL dump
)
308 Chuck_VM_Code
* code
= new Chuck_VM_Code
;
309 code
->num_instr
= emit
->global
->code
.size();
310 code
->instr
= new Chuck_Instr
*[code
->num_instr
];
313 for( unsigned int i
= 0; i
< code
->num_instr
; i
++ )
314 code
->instr
[i
] = emit
->global
->code
[i
];
317 for( unsigned int j
= 0; j
< emit
->functions
.size(); j
++ )
319 Chuck_VM_Code
* code2
= new Chuck_VM_Code
;
320 Chuck_Code
* c
= emit
->functions
[j
];
321 code2
->num_instr
= c
->code
.size();
322 code2
->instr
= new Chuck_Instr
*[code2
->num_instr
];
325 for( unsigned int i
= 0; i
< code2
->num_instr
; i
++ )
326 code2
->instr
[i
] = c
->code
[i
];
329 code2
->stack_depth
= c
->stack_depth
;
333 fprintf( stderr
, "[chuck]: dumping function %s( ... )\n\n", c
->name
.c_str() );
335 for( unsigned int i
= 0; i
< code2
->num_instr
; i
++ )
336 fprintf( stdout
, "'%i' %s( %s )\n", i
,
337 code2
->instr
[i
]->name(), code2
->instr
[i
]->params() );
339 fprintf( stdout
, "...\n\n" );
343 S_enter( g_func2code
, insert_symbol((char *)c
->name
.c_str()), code2
);
352 //------------------------------------------------------------------------------
353 // name: emit_engine_addr_map()
355 //------------------------------------------------------------------------------
356 t_CKBOOL
emit_engine_addr_map( Chuck_Emmission
* emit
, Chuck_VM_Shred
* shred
)
359 uint sp
= (uint
)shred
->mem
->sp
;
361 // offset the initial region
362 sp
+= sizeof(t_CKINT
);
364 // map the offset to pointers
365 for( unsigned int i
= 0; i
< emit
->addr_map
.size(); i
++ )
366 emit
->addr_map
[i
]->set( sp
+ emit
->addr_map
[i
]->get() );
373 //-----------------------------------------------------------------------------
374 // name: emit_engine_resolve()
376 //-----------------------------------------------------------------------------
377 t_CKBOOL
emit_engine_resolve()
379 Func_Link
* f
= NULL
;
380 Chuck_VM_Code
* code
= NULL
;
382 for( unsigned int i
= 0; i
< g_func_links
.size(); i
++ )
385 code
= (Chuck_VM_Code
*)S_look( g_func2code
, f
->name
);
388 EM_error2( 0, "error: cannot resolve function '%s'",
393 f
->op
->set( (uint
)code
);
396 g_func_links
.clear();
404 //-----------------------------------------------------------------------------
406 //-----------------------------------------------------------------------------
407 t_CKBOOL
emit_engine_emit_prog( Chuck_Emmission
* emit
, a_Program prog
);
408 t_CKBOOL
emit_engine_emit_stmt_list( Chuck_Emmission
* emit
, a_Stmt_List list
);
409 t_CKBOOL
emit_engine_emit_stmt( Chuck_Emmission
* emit
, a_Stmt stmt
, t_CKBOOL pop
= TRUE
);
410 t_CKBOOL
emit_engine_emit_code_segment( Chuck_Emmission
* emit
, a_Stmt_Code stmt
);
411 t_CKBOOL
emit_engine_emit_switch( Chuck_Emmission
* emit
, a_Stmt_Switch stmt
);
412 t_CKBOOL
emit_engine_emit_while( Chuck_Emmission
* emit
, a_Stmt_While stmt
);
413 t_CKBOOL
emit_engine_emit_do_while( Chuck_Emmission
* emit
, a_Stmt_While stmt
);
414 t_CKBOOL
emit_engine_emit_until( Chuck_Emmission
* emit
, a_Stmt_Until stmt
);
415 t_CKBOOL
emit_engine_emit_do_until( Chuck_Emmission
* emit
, a_Stmt_Until stmt
);
416 t_CKBOOL
emit_engine_emit_for( Chuck_Emmission
* emit
, a_Stmt_For stmt
);
417 t_CKBOOL
emit_engine_emit_if( Chuck_Emmission
* emit
, a_Stmt_If stmt
);
418 t_CKBOOL
emit_engine_emit_return( Chuck_Emmission
* emit
, a_Stmt_Return stmt
);
419 t_CKBOOL
emit_engine_emit_exp( Chuck_Emmission
* emit
, a_Exp exp
);
420 t_CKBOOL
emit_engine_emit_exp_binary( Chuck_Emmission
* emit
, a_Exp_Binary exp
);
421 t_CKBOOL
emit_engine_emit_exp_unary( Chuck_Emmission
* emit
, a_Exp_Unary exp
);
422 t_CKBOOL
emit_engine_emit_exp_cast( Chuck_Emmission
* emit
, a_Exp_Cast exp
);
423 t_CKBOOL
emit_engine_emit_exp_postfix( Chuck_Emmission
* emit
, a_Exp_Postfix exp
);
424 t_CKBOOL
emit_engine_emit_exp_dur( Chuck_Emmission
* emit
, a_Exp_Dur exp
);
425 t_CKBOOL
emit_engine_emit_exp_primary( Chuck_Emmission
* emit
, a_Exp_Primary exp
);
426 t_CKBOOL
emit_engine_emit_exp_array( Chuck_Emmission
* emit
, a_Exp_Array exp
);
427 t_CKBOOL
emit_engine_emit_exp_func_call( Chuck_Emmission
* emit
, a_Exp_Func_Call exp
, t_CKBOOL spork
= FALSE
);
428 t_CKBOOL
emit_engine_emit_exp_dot_member( Chuck_Emmission
* emit
, a_Exp_Dot_Member exp
, t_Type t
);
429 t_CKBOOL
emit_engine_emit_exp_if( Chuck_Emmission
* emit
, a_Exp_If exp
);
430 t_CKBOOL
emit_engine_emit_exp_decl( Chuck_Emmission
* emit
, a_Exp_Decl exp
);
431 t_CKBOOL
emit_engine_emit_exp_namespace( Chuck_Emmission
* emit
, a_Exp_Namespace nspc
);
432 t_CKBOOL
emit_engine_emit_op( Chuck_Emmission
* emit
, ae_Operator op
, a_Exp lhs
, a_Exp rhs
);
433 t_CKBOOL
emit_engine_emit_chuck( Chuck_Emmission
* emit
, a_Exp lhs
, a_Exp rhs
);
434 t_CKBOOL
emit_engine_emit_unchuck( Chuck_Emmission
* emit
, a_Exp lhs
, a_Exp rhs
);
435 t_CKBOOL
emit_engine_emit_func_def( Chuck_Emmission
* emit
, a_Func_Def func_def
);
436 t_CKBOOL
emit_engine_emit_spork( Chuck_Emmission
* emit
, a_Exp_Func_Call exp
);
438 t_CKBOOL
emit_engine_emit_exp_mem( Chuck_Emmission
* emit
, a_Exp exp
);
439 t_CKBOOL
emit_engine_emit_exp_primary_mem( Chuck_Emmission
* emit
, a_Exp_Primary exp
);
440 t_CKBOOL
emit_engine_emit_exp_dot_member_mem( Chuck_Emmission
* emit
, a_Exp_Dot_Member exp
);
441 t_CKBOOL
emit_engine_emit_exp_array_mem( Chuck_Emmission
* emit
, a_Exp_Array exp
);
442 t_CKBOOL
emit_engine_emit_exp_func_call_mem( Chuck_Emmission
* emit
, a_Exp_Func_Call exp
);
444 t_CKBOOL
emit_engine_emit_symbol( Chuck_Emmission
* emit
, S_Symbol symbol
,
445 t_CKBOOL offset
, int linepos
);
450 //-----------------------------------------------------------------------------
451 // name: emit_engine_init()
453 //-----------------------------------------------------------------------------
454 Chuck_Emmission
* emit_engine_init( t_Env env
)
457 Chuck_Emmission
* emit
= new Chuck_Emmission( env
);
460 EM_error2( 0, "(emit): out of memory!" );
464 if( g_func2code
== NULL
)
465 g_func2code
= S_empty();
468 emit
->global
= new Chuck_Code( "__system_scope__" );
469 emit
->push( "__system_scope__" );
472 //emit->alloc_local( insert_symbol("now"), lookup_value(env, insert_symbol("now") ) );
473 //emit->alloc_local( insert_symbol("samp"), lookup_value(env, insert_symbol("samp") ) );
474 //emit->alloc_local( insert_symbol("ms"), lookup_value(env, insert_symbol("ms") ) );
475 //emit->alloc_local( insert_symbol("second"), lookup_value(env, insert_symbol("second") ) );
476 //emit->alloc_local( insert_symbol("minute"), lookup_value(env, insert_symbol("minute") ) );
477 //emit->alloc_local( insert_symbol("hour"), lookup_value(env, insert_symbol("hour") ) );
478 //emit->alloc_local( insert_symbol("day"), lookup_value(env, insert_symbol("day") ) );
479 //emit->alloc_local( insert_symbol("week"), lookup_value(env, insert_symbol("week") ) );
480 emit
->alloc_local( insert_symbol("stdout"), lookup_value(env
, insert_symbol("stdout") ) );
481 emit
->alloc_local( insert_symbol("stderr"), lookup_value(env
, insert_symbol("stderr") ) );
482 emit
->alloc_local( insert_symbol("chout"), lookup_value(env
, insert_symbol("chout") ) );
483 emit
->alloc_local( insert_symbol("cherr"), lookup_value(env
, insert_symbol("cherr") ) );
484 emit
->alloc_local( insert_symbol("midiin"), lookup_value(env
, insert_symbol("midiin") ) );
485 emit
->alloc_local( insert_symbol("midiout"), lookup_value(env
, insert_symbol("midiout") ) );
486 //emit->alloc_local( insert_symbol("adc"), lookup_value(env, insert_symbol("adc") ) );
487 //emit->alloc_local( insert_symbol("dac"), lookup_value(env, insert_symbol("dac") ) );
490 t_CKDUR second
= Digitalio::sampling_rate() * samp
;
491 t_CKDUR ms
= second
/ 1000.0;
492 t_CKDUR minute
= second
* 60.0;
493 t_CKDUR hour
= minute
* 60.0;
494 t_CKDUR day
= hour
* 24.0;
495 t_CKDUR week
= day
* 7.0;
498 emit
->alloc_dur( insert_symbol("samp"), samp
);
499 emit
->alloc_dur( insert_symbol("ms"), ms
);
500 emit
->alloc_dur( insert_symbol("second"), second
);
501 emit
->alloc_dur( insert_symbol("minute"), minute
);
502 emit
->alloc_dur( insert_symbol("hour"), hour
);
503 emit
->alloc_dur( insert_symbol("day"), day
);
504 emit
->alloc_dur( insert_symbol("week"), week
);
506 emit
->push( "__base_scope__" );
514 //-----------------------------------------------------------------------------
515 // name: emit_engine_shutdown()
517 //-----------------------------------------------------------------------------
518 t_CKBOOL
emit_engine_shutdown( Chuck_Emmission
*& emit
)
520 // delete and set pointer to NULL
530 //-----------------------------------------------------------------------------
531 // name: emit_engine_emit_prog()
532 // desc: emit a program
533 //-----------------------------------------------------------------------------
534 t_CKBOOL
emit_engine_emit_prog( Chuck_Emmission
* emit
, a_Program prog
)
537 Chuck_Instr_Mem_Push_Imm
* op
= new Chuck_Instr_Mem_Push_Imm( 0 );
542 // emit the stack depth - we don't know this yet
547 switch( prog
->section
->s_type
)
549 case ae_section_stmt
:
550 ret
= emit_engine_emit_stmt_list( emit
, prog
->section
->stmt_list
);
553 case ae_section_func
:
554 ret
= emit_engine_emit_func_def( emit
, prog
->section
->func_def
);
557 case ae_section_class
:
566 emit
->append( new Chuck_Instr_EOC
);
567 // set the stack depth now that we know
568 op
->set( emit
->stack_depth() );
576 //-----------------------------------------------------------------------------
577 // name: emit_engine_emit_stmt_list()
578 // desc: emit stmt list
579 //-----------------------------------------------------------------------------
580 t_CKBOOL
emit_engine_emit_stmt_list( Chuck_Emmission
* emit
, a_Stmt_List list
)
587 ret
= emit_engine_emit_stmt( emit
, list
->stmt
);
598 //-----------------------------------------------------------------------------
599 // name: emit_engine_emit_stmt()
601 //-----------------------------------------------------------------------------
602 t_CKBOOL
emit_engine_emit_stmt( Chuck_Emmission
* emit
, a_Stmt stmt
, t_CKBOOL pop
)
609 switch( stmt
->s_type
)
612 // env->print( "stmt_exp" );
613 ret
= emit_engine_emit_exp( emit
, stmt
->stmt_exp
);
614 if( pop
&& stmt
->stmt_exp
->type
->size
> 0 )
616 if( stmt
->stmt_exp
->type
->size
== 4 || stmt
->stmt_exp
->s_type
== ae_exp_decl
)
617 emit
->append( new Chuck_Instr_Reg_Pop_Word
);
618 else if( stmt
->stmt_exp
->type
->size
== 8 )
619 emit
->append( new Chuck_Instr_Reg_Pop_Word2
);
622 EM_error2( stmt
->stmt_exp
->linepos
,
623 "(emit): internal error: %i byte stack item not unhandled",
624 stmt
->stmt_exp
->type
->size
);
631 // env->print( "stmt_if" );
633 ret
= emit_engine_emit_if( emit
, &stmt
->stmt_if
);
638 // env->print( "stmt_for" );
640 ret
= emit_engine_emit_for( emit
, &stmt
->stmt_for
);
645 // env->print( "stmt_while" );
647 if( stmt
->stmt_while
.is_do
)
648 ret
= emit_engine_emit_do_while( emit
, &stmt
->stmt_while
);
650 ret
= emit_engine_emit_while( emit
, &stmt
->stmt_while
);
655 // env->print( "stmt_until" );
657 if( stmt
->stmt_until
.is_do
)
658 ret
= emit_engine_emit_do_until( emit
, &stmt
->stmt_until
);
660 ret
= emit_engine_emit_until( emit
, &stmt
->stmt_until
);
665 // env->print( "stmt_switch" );
671 // env->print( "break? not implemented" );
676 // env->print( "code segment" );
678 ret
= emit_engine_emit_code_segment( emit
, &stmt
->stmt_code
);
682 case ae_stmt_continue
:
683 // env->print( "continue" );
684 // ret = emit_engine_emit_continue( emit, &stmt->stmt_continue );
688 // env->print( "return" );
689 ret
= emit_engine_emit_return( emit
, &stmt
->stmt_return
);
693 // env->print( "case" );
694 // ret = emit_engine_emit_case( emit, &stmt->stmt_case );
697 case ae_stmt_gotolabel
:
698 // env->print( "gotolabel" );
699 // ret = emit_engine_emit_gotolabel( emit, &stmt->stmt_case );
703 EM_error2( stmt
->linepos
,
704 "(emit): internal error: unhandled statement '%i' during emission",
715 //-----------------------------------------------------------------------------
716 // name: emit_engine_emit_exp()
718 //-----------------------------------------------------------------------------
719 t_CKBOOL
emit_engine_emit_exp( Chuck_Emmission
* emit
, a_Exp exp
)
723 switch( exp
->s_type
)
726 if( !emit_engine_emit_exp_binary( emit
, &exp
->binary
) )
731 if( !emit_engine_emit_exp_unary( emit
, &exp
->unary
) )
736 if( !emit_engine_emit_exp_cast( emit
, &exp
->cast
) )
741 if( !emit_engine_emit_exp_postfix( emit
, &exp
->postfix
) )
746 if( !emit_engine_emit_exp_dur( emit
, &exp
->dur
) )
751 if( !emit_engine_emit_exp_primary( emit
, &exp
->primary
) )
756 if( !emit_engine_emit_exp_array( emit
, &exp
->array
) )
760 case ae_exp_func_call
:
761 if( !emit_engine_emit_exp_func_call( emit
, &exp
->func_call
) )
765 case ae_exp_dot_member
:
766 if( !emit_engine_emit_exp_dot_member( emit
, &exp
->dot_member
, exp
->type
) )
771 if( !emit_engine_emit_exp_if( emit
, &exp
->exp_if
) )
776 if( !emit_engine_emit_exp_decl( emit
, &exp
->decl
) )
780 case ae_exp_namespace
:
781 if( !emit_engine_emit_exp_namespace( emit
, &exp
->name_space
) )
786 EM_error2( exp
->linepos
,
787 "(emit): internal error: unhandled expression '%i' in emission!",
801 //-----------------------------------------------------------------------------
802 // name: emit_engine_emit_exp_binary
804 //-----------------------------------------------------------------------------
805 t_CKBOOL
emit_engine_emit_exp_binary( Chuck_Emmission
* emit
, a_Exp_Binary exp
)
807 t_CKBOOL left
= FALSE
;
808 t_CKBOOL right
= FALSE
;
810 // hack for determining if a dot member comes first in chuck chain
811 if( exp
->op
== ae_op_chuck
&& ( exp
->rhs
->s_type
== ae_exp_dot_member
) )
814 exp
->rhs
->dot_member
.flag
= TRUE
;
817 // ^ op should be reversed for midi
818 if( exp
->op
== ae_op_s_xor
&& ( exp
->lhs
->type
->type
== te_midiin
|| exp
->lhs
->type
->type
== te_midiout
) )
820 right
= emit_engine_emit_exp( emit
, exp
->rhs
);
821 left
= emit_engine_emit_exp( emit
, exp
->lhs
);
825 left
= emit_engine_emit_exp( emit
, exp
->lhs
);
826 right
= emit_engine_emit_exp( emit
, exp
->rhs
);
831 if( !left
|| !right
)
835 if( !emit_engine_emit_op( emit
, exp
->op
, exp
->lhs
, exp
->rhs
) )
844 //-----------------------------------------------------------------------------
845 // name: emit_engine_emit_exp_unary
847 //-----------------------------------------------------------------------------
848 t_CKBOOL
emit_engine_emit_exp_unary( Chuck_Emmission
* emit
, a_Exp_Unary exp
)
850 if( exp
->op
!= ae_op_spork
&& !emit_engine_emit_exp( emit
, exp
->exp
) )
856 if( !emit_engine_emit_exp_mem( emit
, exp
->exp
) )
859 if( exp
->exp
->type
->type
== te_int
)
860 emit
->append( new Chuck_Instr_Inc_int
);
861 else if( exp
->exp
->type
->type
== te_uint
)
862 emit
->append( new Chuck_Instr_Inc_uint
);
865 EM_error2( exp
->linepos
,
866 "(emit): internal error: unhandled type '%s' for pre '++'' operator",
867 exp
->exp
->type
->name
);
872 case ae_op_minusminus
:
873 if( !emit_engine_emit_exp_mem( emit
, exp
->exp
) )
876 if( exp
->exp
->type
->type
== te_int
)
877 emit
->append( new Chuck_Instr_Dec_int
);
878 else if( exp
->exp
->type
->type
== te_uint
)
879 emit
->append( new Chuck_Instr_Dec_uint
);
882 EM_error2( exp
->linepos
,
883 "(emit): internal error: unhandled type '%s' for pre '--' operator",
884 exp
->exp
->type
->name
);
890 if( exp
->exp
->type
->type
== te_int
)
891 emit
->append( new Chuck_Instr_Complement_int
);
892 else if( exp
->exp
->type
->type
== te_uint
)
893 emit
->append( new Chuck_Instr_Complement_uint
);
896 EM_error2( exp
->linepos
,
897 "(emit): internal error: unhandled type '%s' for '~' operator",
898 exp
->exp
->type
->name
);
903 case ae_op_exclamation
:
904 if( exp
->exp
->type
->type
== te_int
|| exp
->exp
->type
->type
== te_uint
)
905 emit
->append( new Chuck_Instr_Not_int
);
908 EM_error2( exp
->linepos
,
909 "(emit): internal error: unhandled type '%s' for '!' operator",
910 exp
->exp
->type
->name
);
916 if( exp
->exp
->type
->type
== te_int
|| exp
->exp
->type
->type
== te_uint
)
917 emit
->append( new Chuck_Instr_Negate_int
);
918 else if( exp
->exp
->type
->type
== te_float
)
919 emit
->append( new Chuck_Instr_Negate_double
);
922 EM_error2( exp
->linepos
,
923 "(emit): internal error: unhandled type '%s' for unary '-' operator",
924 exp
->exp
->type
->name
);
930 if( exp
->exp
->s_type
== ae_exp_func_call
)
932 if( !emit_engine_emit_spork( emit
, &exp
->exp
->func_call
) )
937 EM_error2( exp
->linepos
,
938 "(emit): internal error: sporking non-function call..." );
943 EM_error2( exp
->linepos
,
944 "(emit): internal error: unhandled unary op '%i",
955 //-----------------------------------------------------------------------------
956 // name: emit_engine_emit_spork
958 //-----------------------------------------------------------------------------
959 t_CKBOOL
emit_engine_emit_spork( Chuck_Emmission
* emit
, a_Exp_Func_Call exp
)
961 // emit the function call
962 if( !emit_engine_emit_exp_func_call( emit
, exp
, true ) )
971 //-----------------------------------------------------------------------------
972 // name: emit_engine_emit_spork
974 //-----------------------------------------------------------------------------
975 t_CKBOOL
emit_engine_emit_spork( Chuck_Emmission
* emit
, a_Exp exp
)
977 Chuck_Emmission
* emit2
= emit_engine_init( emit
->env
);
979 Chuck_Instr_Mem_Push_Imm
* op
= new Chuck_Instr_Mem_Push_Imm( 0 );
981 // emit the stack depth - we don't know this yet
984 // emit the function call
985 if( !emit_engine_emit_exp( emit2
, exp
) )
989 emit2
->append( new Chuck_Instr_EOC
);
990 // set the stack depth now that we know
991 op
->set( emit2
->stack_depth() );
994 Chuck_VM_Code
* code
= emit_to_code( emit2
);
995 code
->name
= string("spork ~ exp");
996 emit
->append( new Chuck_Instr_Reg_Push_Imm( (uint
)code
) );
997 emit
->append( new Chuck_Instr_Spork
);
1005 //-----------------------------------------------------------------------------
1006 // name: emit_get_cast_instr()
1008 //-----------------------------------------------------------------------------
1009 t_CKBOOL
emit_get_cast_instr( Chuck_Emmission
* emit
, t_Type to
, t_Type from
)
1011 if( to
->type
== from
->type
) return TRUE
;
1013 if( to
->type
== te_int
&& from
->type
== te_float
)
1014 emit
->append( new Chuck_Instr_Cast_double2int
);
1015 else if( to
->type
== te_float
&& from
->type
== te_int
)
1016 emit
->append( new Chuck_Instr_Cast_int2double
);
1019 EM_error2( 0, "(emit): internal error: no instruction for casting type '%s' to '%s'",
1020 from
->name
, to
->name
);
1030 //-----------------------------------------------------------------------------
1031 // name: emit_engine_emit_exp_cast
1033 //-----------------------------------------------------------------------------
1034 t_CKBOOL
emit_engine_emit_exp_cast( Chuck_Emmission
* emit
, a_Exp_Cast exp
)
1036 if( !emit_engine_emit_exp( emit
, exp
->exp
) )
1038 if( !emit_get_cast_instr( emit
, lookup_type( emit
->env
, exp
->type
, TRUE
),
1048 //-----------------------------------------------------------------------------
1049 // name: emit_engine_emit_exp_postfix
1051 //-----------------------------------------------------------------------------
1052 t_CKBOOL
emit_engine_emit_exp_postfix( Chuck_Emmission
* emit
, a_Exp_Postfix exp
)
1054 // emit the exp inside
1055 if( !emit_engine_emit_exp( emit
, exp
->exp
) )
1060 case ae_op_plusplus
:
1061 if( !emit_engine_emit_exp_mem( emit
, exp
->exp
) )
1063 EM_error2( exp
->linepos
,
1064 "(emit): internal error: emitting [mem] exp from postfix..." );
1068 if( exp
->exp
->type
->type
== te_int
)
1069 emit
->append( new Chuck_Instr_Inc_int
);
1070 else if( exp
->exp
->type
->type
== te_uint
)
1071 emit
->append( new Chuck_Instr_Inc_uint
);
1074 EM_error2( exp
->linepos
,
1075 "(emit): internal error: unhandled type '%s' for post '++' operator",
1076 exp
->exp
->type
->name
);
1081 case ae_op_minusminus
:
1082 if( !emit_engine_emit_exp_mem( emit
, exp
->exp
) )
1084 EM_error2( exp
->linepos
,
1085 "(emit): internal error: emitting [mem] exp from postfix..." );
1089 if( exp
->exp
->type
->type
== te_int
)
1090 emit
->append( new Chuck_Instr_Dec_int
);
1091 else if( exp
->exp
->type
->type
== te_uint
)
1092 emit
->append( new Chuck_Instr_Dec_uint
);
1095 EM_error2( exp
->linepos
,
1096 "(emit): internal error: unhandled type '%s' for post '--' operator",
1097 exp
->exp
->type
->name
);
1103 EM_error2( exp
->linepos
,
1104 "(emit): internal error: unhandled postfix operator '%i'",
1115 //-----------------------------------------------------------------------------
1116 // name: emit_engine_emit_exp_dur
1118 //-----------------------------------------------------------------------------
1119 t_CKBOOL
emit_engine_emit_exp_dur( Chuck_Emmission
* emit
, a_Exp_Dur exp
)
1121 if( !emit_engine_emit_exp( emit
, exp
->base
) )
1125 if( exp
->base
->type
->type
== te_int
)
1126 emit
->append( new Chuck_Instr_Cast_int2double
);
1128 if( !emit_engine_emit_exp( emit
, exp
->unit
) )
1132 emit
->append( new Chuck_Instr_Times_double
);
1140 //-----------------------------------------------------------------------------
1141 // name: emit_engine_emit_symbol
1143 //-----------------------------------------------------------------------------
1144 t_CKBOOL
emit_engine_emit_symbol( Chuck_Emmission
* emit
, S_Symbol id
,
1145 t_CKBOOL off
, int linepos
)
1147 t_CKUINT is_global
= FALSE
;
1149 int offset
= off
? emit
->find_offset( id
, &is_global
, &size
) : -1;
1152 // could be a function
1153 t_Type t
= lookup_value( emit
->nspc
, id
);
1154 if( t
&& t
->type
== te_function
)
1156 a_Func_Def func
= lookup_func( emit
->nspc
, id
, FALSE
);
1157 if( !func
|| ( func
&& func
->s_type
== ae_func_user
) )
1159 Func_Link
* f
= (Func_Link
*)checked_malloc( sizeof( Func_Link
) );
1161 emit
->append( f
->op
= new Chuck_Instr_Reg_Push_Imm( 0 ) );
1162 g_func_links
.push_back( f
);
1164 else // func && func->s_type == ae_func_builtin
1166 emit
->nspc_func
= func
;
1167 emit
->append( new Chuck_Instr_Reg_Push_Imm( func
->stack_depth
) );
1168 emit
->append( new Chuck_Instr_Reg_Push_Imm(
1169 (uint
)func
->builtin
) );
1172 else if( t
&& t
->type
== __te_system_namespace__
)
1174 // find the namespace
1175 emit
->nspc
= lookup_namespace( emit
->env
, id
, FALSE
);
1179 "(emit): internal error: cannot find namespace '%s'",
1184 else if( t
&& t
->type
== __te_system_class__
)
1188 "(emit): internal error: class/lookup not impl" );
1191 else if( emit
->nspc
&& ( t
= lookup_value( emit
->nspc
, id
, FALSE
) ) )
1193 void * addr
= lookup_addr( emit
->nspc
, id
, FALSE
);
1197 "(emit): internal error looking up addr for '%s.%s'",
1198 "[namespace]", S_name(id
) );
1203 if( t
->size
== 4 || t
->size
== 8 )
1204 emit
->append( new Chuck_Instr_Reg_Push_Deref( (uint
)addr
, t
->size
) );
1208 "(emit): internal error resolving '%s.%s'",
1209 "[namespace]", S_name(id
) );
1217 "(emit): internal error resolving var '%s'",
1224 if( emit
->is_global
|| !is_global
)
1227 emit
->append( new Chuck_Instr_Reg_Push_Mem( offset
) );
1228 else if( size
== 8 )
1229 emit
->append( new Chuck_Instr_Reg_Push_Mem2( offset
) );
1233 "(emit): internal error with reg push %i",
1238 else // local and global
1240 Chuck_Instr_Unary_Op
* op
= NULL
;
1241 // the offset is not set yet
1242 emit
->append( op
= new Chuck_Instr_Reg_Push_Deref( offset
, size
) );
1243 // queue for addr translation later
1244 emit
->addr_map
.push_back( op
);
1254 //-----------------------------------------------------------------------------
1255 // name: emit_engine_emit_exp_primary
1257 //-----------------------------------------------------------------------------
1258 t_CKBOOL
emit_engine_emit_exp_primary( Chuck_Emmission
* emit
, a_Exp_Primary exp
)
1262 Chuck_Instr_Unary_Op
* op
= NULL
, * op2
= NULL
;
1264 switch( exp
->s_type
)
1266 case ae_primary_var
:
1267 if( exp
->var
== insert_symbol( "now" ) )
1269 emit
->append( new Chuck_Instr_Reg_Push_Now
);
1271 else if( exp
->var
== insert_symbol( "start" ) )
1273 emit
->append( new Chuck_Instr_Reg_Push_Start
);
1275 else if( exp
->var
== insert_symbol( "midiin" ) )
1277 if( emit
->get_op() )
1279 EM_error2( exp
->linepos
,
1280 "MIDI in should be drained by using => before invoking again" );
1284 emit
->append( op
= new Chuck_Instr_Midi_In(0) );
1285 emit
->append( op2
= new Chuck_Instr_Midi_In_Go(0) );
1286 emit
->push_op( op2
);
1287 emit
->push_op( op
);
1289 else if( exp
->var
== insert_symbol( "midiout" ) )
1291 if( emit
->get_op() )
1293 EM_error2( exp
->linepos
,
1294 "MIDI out should be drained by using => before invoking again" );
1298 emit
->append( op
= new Chuck_Instr_Midi_Out(0) );
1299 emit
->append( op2
= new Chuck_Instr_Midi_Out_Go(0) );
1300 emit
->push_op( op2
);
1301 emit
->push_op( op
);
1303 else if( exp
->var
== insert_symbol( "dac" ) )
1305 emit
->append( new Chuck_Instr_DAC
);
1307 else if( exp
->var
== insert_symbol( "adc" ) )
1309 emit
->append( new Chuck_Instr_ADC
);
1311 else if( exp
->var
== insert_symbol( "bunghole" ) )
1313 emit
->append( new Chuck_Instr_Bunghole
);
1315 else if( exp
->var
== insert_symbol( "blackhole" ) )
1317 emit
->append( new Chuck_Instr_Bunghole
);
1319 else if( exp
->var
== insert_symbol( "true" ) )
1321 emit
->append( new Chuck_Instr_Reg_Push_Imm( 1 ) );
1323 else if( exp
->var
== insert_symbol( "false" ) )
1325 emit
->append( new Chuck_Instr_Reg_Push_Imm( 0 ) );
1327 else if( exp
->var
== insert_symbol("maybe") )
1329 emit
->append( new Chuck_Instr_Reg_Push_Maybe() );
1331 else if( exp
->var
== insert_symbol( "pi" ) )
1333 double pi
= 3.14159265358979323846;
1334 emit
->append( new Chuck_Instr_Reg_Push_Imm2( pi
) );
1336 else if( exp
->var
== insert_symbol( "endl" ) )
1338 emit
->append( new Chuck_Instr_Reg_Push_Imm( (uint
)"\n" ) );
1340 else if( exp
->var
== insert_symbol( "stdout" ) ||
1341 exp
->var
== insert_symbol( "chout" ) )
1343 emit
->append( new Chuck_Instr_Reg_Push_Imm( 0 ) );
1345 else if( emit
->find_dur( exp
->var
, &dur
) )
1347 emit
->append( new Chuck_Instr_Reg_Push_Imm2( dur
) );
1352 return emit_engine_emit_symbol( emit
, exp
->var
, TRUE
, exp
->linepos
);
1356 case ae_primary_num
:
1357 memcpy( &temp
, &exp
->num
, sizeof(temp
) );
1358 emit
->append( new Chuck_Instr_Reg_Push_Imm( temp
) );
1361 case ae_primary_uint
:
1362 emit
->append( new Chuck_Instr_Reg_Push_Imm( exp
->num2
) );
1365 case ae_primary_float
:
1366 emit
->append( new Chuck_Instr_Reg_Push_Imm2( exp
->fnum
) );
1369 case ae_primary_str
:
1370 temp
= (uint
)exp
->str
;
1371 emit
->append( new Chuck_Instr_Reg_Push_Imm( temp
) );
1374 case ae_primary_exp
:
1375 emit_engine_emit_exp( emit
, exp
->exp
);
1385 //-----------------------------------------------------------------------------
1386 // name: emit_engine_emit_exp_array
1388 //-----------------------------------------------------------------------------
1389 t_CKBOOL
emit_engine_emit_exp_array( Chuck_Emmission
* emit
, a_Exp_Array exp
)
1397 //-----------------------------------------------------------------------------
1398 // name: emit_engine_emit_exp_func_call
1400 //-----------------------------------------------------------------------------
1401 t_CKBOOL
emit_engine_emit_exp_func_call( Chuck_Emmission
* emit
, a_Exp_Func_Call exp
,
1407 if( !emit_engine_emit_exp( emit
, exp
->args
) )
1409 EM_error2( exp
->linepos
,
1410 "(emit): internal error in emitting function call arguments..." );
1416 Chuck_Emmission
* emit_save
= emit
;
1417 Chuck_Instr_Mem_Push_Imm
* op
= NULL
;
1420 emit
= emit_engine_init( emit
->env
);
1421 op
= new Chuck_Instr_Mem_Push_Imm( 0 );
1422 // emit the stack depth - we don't know this yet
1427 if( !emit_engine_emit_exp( emit
, exp
->func
) )
1429 EM_error2( exp
->linepos
,
1430 "(emit): internal error in evaluating function call..." );
1434 // push the local stack depth
1435 emit
->append( new Chuck_Instr_Reg_Push_Imm( emit
->stack_depth() ) );
1437 // call the function
1438 if( emit
->nspc_func
&& emit
->nspc_func
->s_type
== ae_func_builtin
)
1440 if( exp
->ret_type
->size
== 0 )
1441 emit
->append( new Chuck_Instr_Func_Call0
);
1442 else if( exp
->ret_type
->size
== 4 )
1443 emit
->append( new Chuck_Instr_Func_Call2
);
1444 else if( exp
->ret_type
->size
== 8 )
1445 emit
->append( new Chuck_Instr_Func_Call3
);
1448 EM_error2( exp
->linepos
,
1449 "(emit): internal error: %i func call not handled",
1450 exp
->ret_type
->size
);
1456 Chuck_Instr
* op
= new Chuck_Instr_Func_Call
;
1464 emit
->append( new Chuck_Instr_EOC
);
1465 // set the stack depth now that we know
1466 op
->set( emit
->stack_depth() );
1469 Chuck_VM_Code
* code
= emit_to_code( emit
);
1470 code
->name
= string("spork ~ exp");
1473 a_Exp e
= exp
->args
;
1475 while( e
) { size
+= e
->type
->size
; e
=e
->next
; }
1476 emit
->append( new Chuck_Instr_Reg_Push_Imm( (uint
)code
) );
1477 emit
->append( new Chuck_Instr_Spork( size
) );
1481 emit
->nspc
= emit
->env
;
1482 emit
->nspc_func
= NULL
;
1490 //-----------------------------------------------------------------------------
1491 // name: emit_engine_emit_exp_dot_member
1493 //-----------------------------------------------------------------------------
1494 t_CKBOOL
emit_engine_emit_exp_dot_member( Chuck_Emmission
* emit
, a_Exp_Dot_Member exp
, t_Type t
)
1496 t_Type t_base
= exp
->base
->type
;
1499 // namespace or class
1500 if( t_base
->type
== __te_system_namespace__
)
1503 emit_engine_emit_exp( emit
, exp
->base
);
1505 emit_engine_emit_symbol( emit
, exp
->id
, FALSE
, exp
->linepos
);
1507 else if( isa( t_base
, lookup_type( emit
->env
, insert_symbol( "ugen" ) ) ) )
1510 emit_engine_emit_exp( emit
, exp
->base
);
1514 // EM_error2( exp->linepos,
1515 // "(emit): internal error: no ctrl for '%s.%s'",
1516 // t_base->name, S_name(exp->id) );
1520 //emit->append( new Chuck_Instr_Reg_Push_Imm( exp->data ) );
1523 if( exp
->flag
== 0 )
1525 if( exp
->data2
== 0 )
1527 EM_error2( exp
->linepos
,
1528 "(emit): internal error: cannot read from ugen parameter '%s.%s', it is write-only",
1529 t_base
->name
, S_name(exp
->id
) );
1533 // the cget function addr
1534 emit
->append( new Chuck_Instr_Reg_Push_Imm( exp
->data2
) );
1537 if( !strcmp( S_name(exp
->id
), "op" ) )
1538 emit
->append( new Chuck_Instr_UGen_CGet_Op
);
1539 else if( !strcmp( S_name(exp
->id
), "gain" ) )
1540 emit
->append( new Chuck_Instr_UGen_CGet_Gain
);
1541 else if( !strcmp( S_name(exp
->id
), "last" ) )
1542 emit
->append( new Chuck_Instr_UGen_CGet_Last
);
1545 // cget passing to ugen
1547 emit
->append( new Chuck_Instr_UGen_CGet
);
1548 else if( t
->size
== 8 )
1549 emit
->append( new Chuck_Instr_UGen_CGet2
);
1552 EM_error2( exp
->linepos
,
1553 "(emit): internal error: %i ugen cget not handled",
1562 EM_error2( exp
->linepos
,
1563 "(emit): internal error: class.member not impl" );
1573 //-----------------------------------------------------------------------------
1574 // name: emit_engine_emit_exp_if
1576 //-----------------------------------------------------------------------------
1577 t_CKBOOL
emit_engine_emit_exp_if( Chuck_Emmission
* emit
, a_Exp_If exp
)
1585 //-----------------------------------------------------------------------------
1586 // name: emit_engine_emit_exp_decl
1588 //-----------------------------------------------------------------------------
1589 t_CKBOOL
emit_engine_emit_exp_decl( Chuck_Emmission
* emit
, a_Exp_Decl exp
)
1591 a_Var_Decl_List list
= exp
->var_decl_list
;
1592 a_Var_Decl var_decl
= NULL
;
1596 var_decl
= list
->var_decl
;
1597 t_Type type
= lookup_type( emit
->env
, exp
->type
);
1599 if( var_decl
->isarray
)
1601 EM_error2( exp
->linepos
,
1602 "(emit): internal error: array not impl" );
1608 emit
->append( new Chuck_Instr_Reg_Push_Imm(
1609 emit
->alloc_local( var_decl
->id
, type
) ) );
1612 if( isa( type
, lookup_type(emit
->env
, insert_symbol("ugen")) ) )
1614 Chuck_UGen_Info
* info
= lookup_ugen( emit
->nspc
, exp
->type
);
1617 EM_error2( exp
->linepos
,
1618 "(emit): internal error: undefined ugen type '%s'",
1619 S_name(var_decl
->id
) );
1622 emit
->append( new Chuck_Instr_Reg_Push_Imm( (uint
)info
) );
1623 emit
->append( new Chuck_Instr_UGen_Alloc() );
1624 emit
->append( new Chuck_Instr_Chuck_Assign_Object2
);
1637 //-----------------------------------------------------------------------------
1638 // name: emit_engine_emit_exp_namespace()
1640 //-----------------------------------------------------------------------------
1641 t_CKBOOL
emit_engine_emit_exp_namespace( Chuck_Emmission
* emit
, a_Exp_Namespace exp
)
1644 emit
->append( new Chuck_Instr_Reg_Push_Imm( (t_CKUINT
)S_name(exp
->name
) ) );
1651 //-----------------------------------------------------------------------------
1652 // name: emit_engine_emit_op()
1654 //-----------------------------------------------------------------------------
1655 t_CKBOOL
emit_engine_emit_op( Chuck_Emmission
* emit
,
1656 ae_Operator op
, a_Exp lhs
, a_Exp rhs
)
1658 te_Type left
= lhs
->type
->type
;
1659 te_Type right
= rhs
->type
->type
;
1664 // ----------------------------- num --------------------------------------
1667 if( ( left
== te_dur
&& right
== te_time
) ||
1668 ( left
== te_time
&& right
== te_dur
) )
1669 emit
->append( new Chuck_Instr_Add_double
);
1675 emit
->append( new Chuck_Instr_Add_int
);
1678 emit
->append( new Chuck_Instr_Add_uint
);
1681 emit
->append( new Chuck_Instr_Add_double
);
1684 emit
->append( new Chuck_Instr_Add_double
);
1688 EM_error2( lhs
->linepos
,
1689 "(emit): internal error: unhandled type '%i' in binary op '+'",
1697 if( ( left
== te_time
&& right
== te_dur
) )
1698 emit
->append( new Chuck_Instr_Minus_double
);
1699 else if( ( left
== te_time
&& right
== te_time
) ) // XXX time - time = dur
1700 emit
->append( new Chuck_Instr_Minus_double
);
1706 emit
->append( new Chuck_Instr_Minus_int
);
1709 emit
->append( new Chuck_Instr_Minus_uint
);
1712 emit
->append( new Chuck_Instr_Minus_double
);
1715 emit
->append( new Chuck_Instr_Minus_double
);
1719 EM_error2( lhs
->linepos
,
1720 "(emit): internal error: unhandled '%i' in binary op '-'",
1731 emit
->append( new Chuck_Instr_Times_int
);
1734 emit
->append( new Chuck_Instr_Times_uint
);
1737 emit
->append( new Chuck_Instr_Times_double
);
1740 emit
->append( new Chuck_Instr_Times_double
);
1744 EM_error2( lhs
->linepos
,
1745 "(emit): internal error: unhandled type '%i' in binary op '*'",
1755 emit
->append( new Chuck_Instr_Divide_int
);
1758 emit
->append( new Chuck_Instr_Divide_uint
);
1761 emit
->append( new Chuck_Instr_Divide_double
);
1764 emit
->append( new Chuck_Instr_Divide_double
);
1768 EM_error2( lhs
->linepos
,
1769 "(emit): internal error: unhandled type '%i' in binary op '/'",
1780 emit
->append( new Chuck_Instr_Binary_Or
);
1784 EM_error2( lhs
->linepos
,
1785 "(emit): internal error: unhandled type '%i' in binary op '|'",
1796 emit
->append( new Chuck_Instr_Binary_And
);
1800 EM_error2( lhs
->linepos
,
1801 "(emit): internal error: unhandled type '%i' in binary op '&'",
1807 case ae_op_shift_left
:
1812 emit
->append( new Chuck_Instr_Binary_Shift_Left
);
1816 EM_error2( lhs
->linepos
,
1817 "(emit): internal error: unhandled type '%i' in binary op '<<'",
1823 case ae_op_shift_right
:
1828 emit
->append( new Chuck_Instr_Binary_Shift_Right
);
1832 EM_error2( lhs
->linepos
,
1833 "(emit): internal error: unhandled type '%i' in binary op '>>'",
1843 emit
->append( new Chuck_Instr_Mod_int
);
1846 emit
->append( new Chuck_Instr_Mod_uint
);
1851 emit
->append( new Chuck_Instr_Mod_double
);
1855 EM_error2( lhs
->linepos
,
1856 "(emit): internal error: unhandled type '%i' in binary op '%%'",
1867 emit
->append( new Chuck_Instr_Binary_Xor
);
1871 Chuck_Instr_Unary_Op
* op
= emit
->get_op();
1874 EM_error2( lhs
->linepos
,
1875 "(emit): internal error: in binary op '%i'", left
);
1878 op
->set( op
->get() | 1 );
1879 // emit->append_ops();
1884 Chuck_Instr_Unary_Op
* op
= emit
->get_op();
1887 EM_error2( lhs
->linepos
,
1888 "(emit): internal error: in binary op '%i'", left
);
1891 op
->set( op
->get() | 1 );
1892 // emit->append_ops();
1896 EM_error2( lhs
->linepos
,
1897 "(emit): internal error: unhandled type '%i' in binary op '^'",
1903 // ----------------------------- chuck -------------------------------------
1907 a_Exp cl
= lhs
, cr
= rhs
;
1914 if( !emit_engine_emit_chuck( emit
, cl
, cr
) )
1926 a_Exp cl
= lhs
, cr
= rhs
;
1933 if( !emit_engine_emit_unchuck( emit
, cl
, cr
) )
1943 case ae_op_at_chuck
:
1949 case ae_op_plus_chuck
:
1952 case ae_op_minus_chuck
:
1955 case ae_op_times_chuck
:
1958 case ae_op_divide_chuck
:
1961 case ae_op_s_and_chuck
:
1964 case ae_op_s_or_chuck
:
1967 case ae_op_s_xor_chuck
:
1970 case ae_op_shift_right_chuck
:
1973 case ae_op_shift_left_chuck
:
1976 case ae_op_percent_chuck
:
1979 // -------------------------------- bool -----------------------------------
1985 emit
->append( new Chuck_Instr_Eq_int
);
1988 emit
->append( new Chuck_Instr_Eq_uint
);
1991 emit
->append( new Chuck_Instr_Eq_double
);
1994 emit
->append( new Chuck_Instr_Eq_double
);
1997 emit
->append( new Chuck_Instr_Eq_double
);
2001 EM_error2( lhs
->linepos
,
2002 "(emit): internal error: unhandled type '%i' in binary op '=='",
2012 emit
->append( new Chuck_Instr_Neq_int
);
2015 emit
->append( new Chuck_Instr_Neq_uint
);
2018 emit
->append( new Chuck_Instr_Neq_double
);
2021 emit
->append( new Chuck_Instr_Neq_double
);
2024 emit
->append( new Chuck_Instr_Neq_double
);
2028 EM_error2( lhs
->linepos
,
2029 "(emit): internal error: unhandled type '%i' in binary op '!='",
2039 emit
->append( new Chuck_Instr_Lt_int
);
2042 emit
->append( new Chuck_Instr_Lt_uint
);
2045 emit
->append( new Chuck_Instr_Lt_double
);
2048 emit
->append( new Chuck_Instr_Lt_double
);
2051 emit
->append( new Chuck_Instr_Lt_double
);
2055 EM_error2( lhs
->linepos
,
2056 "(emit): internal error: unhandled type '%i' in binary op '<'",
2066 emit
->append( new Chuck_Instr_Le_int
);
2069 emit
->append( new Chuck_Instr_Le_uint
);
2072 emit
->append( new Chuck_Instr_Le_double
);
2075 emit
->append( new Chuck_Instr_Le_double
);
2078 emit
->append( new Chuck_Instr_Le_double
);
2082 EM_error2( lhs
->linepos
,
2083 "(emit): internal error: unhandled type '%i' in binary op '<='",
2093 emit
->append( new Chuck_Instr_Gt_int
);
2096 emit
->append( new Chuck_Instr_Gt_uint
);
2099 emit
->append( new Chuck_Instr_Gt_double
);
2102 emit
->append( new Chuck_Instr_Gt_double
);
2105 emit
->append( new Chuck_Instr_Gt_double
);
2109 EM_error2( lhs
->linepos
,
2110 "(emit): internal error: unhandled type '%i' in binary op '>='",
2120 emit
->append( new Chuck_Instr_Ge_int
);
2123 emit
->append( new Chuck_Instr_Ge_uint
);
2126 emit
->append( new Chuck_Instr_Ge_double
);
2129 emit
->append( new Chuck_Instr_Ge_double
);
2132 emit
->append( new Chuck_Instr_Ge_double
);
2136 EM_error2( lhs
->linepos
,
2137 "(emit): internal error: unhandled type '%i' in binary op '>='",
2151 emit
->append( new Chuck_Instr_And
);
2155 EM_error2( lhs
->linepos
,
2156 "(emit): internal error: unhandled type '%i' in binary op '&&'",
2170 emit
->append( new Chuck_Instr_Or
);
2174 EM_error2( lhs
->linepos
,
2175 "(emit): internal error: unhandled type '%i' in binary op '||'",
2182 EM_error2( lhs
->linepos
,
2183 "(emit): internal error: op '%i' not handled",
2194 //------------------------------------------------------------------------------
2195 // name: emit_engine_emit_while()
2197 //------------------------------------------------------------------------------
2198 t_CKBOOL
emit_engine_emit_while( Chuck_Emmission
* emit
, a_Stmt_While stmt
)
2200 t_CKBOOL ret
= TRUE
;
2201 Chuck_Instr_Branch_Op
* op
= NULL
;
2202 uint start_index
= emit
->next_index();
2205 emit_engine_emit_exp( emit
, stmt
->cond
);
2207 switch( stmt
->cond
->type
->type
)
2212 emit
->append( new Chuck_Instr_Reg_Push_Imm( 0 ) );
2213 op
= new Chuck_Instr_Branch_Eq_uint( 0 );
2219 emit
->append( new Chuck_Instr_Reg_Push_Imm2( 0.0 ) );
2220 op
= new Chuck_Instr_Branch_Eq_double( 0 );
2224 EM_error2( stmt
->cond
->linepos
,
2225 "(emit): internal error: unhandled type '%s' in while conditional",
2226 stmt
->cond
->type
->name
);
2234 emit_engine_emit_stmt( emit
, stmt
->body
);
2236 // go back to do check the condition
2237 emit
->append( new Chuck_Instr_Goto( start_index
) );
2239 // set the op's target
2240 op
->set( emit
->next_index() );
2248 //------------------------------------------------------------------------------
2249 // name: emit_engine_emit_do_while()
2251 //------------------------------------------------------------------------------
2252 t_CKBOOL
emit_engine_emit_do_while( Chuck_Emmission
* emit
, a_Stmt_While stmt
)
2254 t_CKBOOL ret
= TRUE
;
2255 Chuck_Instr_Branch_Op
* op
= NULL
;
2256 uint start_index
= emit
->next_index();
2259 emit_engine_emit_stmt( emit
, stmt
->body
);
2262 emit_engine_emit_exp( emit
, stmt
->cond
);
2264 switch( stmt
->cond
->type
->type
)
2269 emit
->append( new Chuck_Instr_Reg_Push_Imm( 0 ) );
2270 op
= new Chuck_Instr_Branch_Neq_uint( 0 );
2276 emit
->append( new Chuck_Instr_Reg_Push_Imm2( 0.0 ) );
2277 op
= new Chuck_Instr_Branch_Neq_double( 0 );
2281 EM_error2( stmt
->cond
->linepos
,
2282 "(emit): internal error: unhandled type '%s' in do/while conditional",
2283 stmt
->cond
->type
->name
);
2290 // set the op's target
2291 op
->set( start_index
);
2299 //------------------------------------------------------------------------------
2300 // name: emit_engine_emit_until()
2302 //------------------------------------------------------------------------------
2303 t_CKBOOL
emit_engine_emit_until( Chuck_Emmission
* emit
, a_Stmt_Until stmt
)
2305 t_CKBOOL ret
= TRUE
;
2306 Chuck_Instr_Branch_Op
* op
= NULL
;
2307 uint start_index
= emit
->next_index();
2310 emit_engine_emit_exp( emit
, stmt
->cond
);
2312 switch( stmt
->cond
->type
->type
)
2317 emit
->append( new Chuck_Instr_Reg_Push_Imm( 0 ) );
2318 op
= new Chuck_Instr_Branch_Neq_uint( 0 );
2324 emit
->append( new Chuck_Instr_Reg_Push_Imm2( 0.0 ) );
2325 op
= new Chuck_Instr_Branch_Neq_double( 0 );
2329 EM_error2( stmt
->cond
->linepos
,
2330 "(emit): internal error: unhandled type '%s' in until conditional",
2331 stmt
->cond
->type
->name
);
2339 emit_engine_emit_stmt( emit
, stmt
->body
);
2341 // go back to do check the condition
2342 emit
->append( new Chuck_Instr_Goto( start_index
) );
2344 // set the op's target
2345 op
->set( emit
->next_index() );
2353 //------------------------------------------------------------------------------
2354 // name: emit_engine_emit_do_until()
2356 //------------------------------------------------------------------------------
2357 t_CKBOOL
emit_engine_emit_do_until( Chuck_Emmission
* emit
, a_Stmt_Until stmt
)
2359 t_CKBOOL ret
= TRUE
;
2360 Chuck_Instr_Branch_Op
* op
= NULL
;
2361 uint start_index
= emit
->next_index();
2364 emit_engine_emit_stmt( emit
, stmt
->body
);
2367 emit_engine_emit_exp( emit
, stmt
->cond
);
2369 switch( stmt
->cond
->type
->type
)
2374 emit
->append( new Chuck_Instr_Reg_Push_Imm( 0 ) );
2375 op
= new Chuck_Instr_Branch_Eq_uint( 0 );
2381 emit
->append( new Chuck_Instr_Reg_Push_Imm2( 0.0 ) );
2382 op
= new Chuck_Instr_Branch_Eq_double( 0 );
2386 EM_error2( stmt
->cond
->linepos
,
2387 "(emit): internal error: unhandled type '%s' in do/until conditional",
2388 stmt
->cond
->type
->name
);
2395 // set the op's target
2396 op
->set( start_index
);
2404 //------------------------------------------------------------------------------
2405 // name: emit_engine_emit_for()
2407 //------------------------------------------------------------------------------
2408 t_CKBOOL
emit_engine_emit_for( Chuck_Emmission
* emit
, a_Stmt_For stmt
)
2410 t_CKBOOL ret
= TRUE
;
2411 Chuck_Instr_Branch_Op
* op
= NULL
;
2414 emit_engine_emit_stmt( emit
, stmt
->c1
);
2416 uint start_index
= emit
->next_index();
2419 emit_engine_emit_stmt( emit
, stmt
->c2
, FALSE
);
2424 switch( stmt
->c2
->stmt_exp
->type
->type
)
2429 emit
->append( new Chuck_Instr_Reg_Push_Imm( 0 ) );
2430 op
= new Chuck_Instr_Branch_Eq_uint( 0 );
2436 emit
->append( new Chuck_Instr_Reg_Push_Imm2( 0.0 ) );
2437 op
= new Chuck_Instr_Branch_Eq_double( 0 );
2441 EM_error2( stmt
->c2
->stmt_exp
->linepos
,
2442 "(emit): internal error: unhandled type '%s' in for conditional",
2443 stmt
->c2
->stmt_exp
->type
->name
);
2451 emit_engine_emit_stmt( emit
, stmt
->body
);
2454 emit_engine_emit_exp( emit
, stmt
->c3
);
2456 if( stmt
->c3
->type
->size
== 8 )
2457 emit
->append( new Chuck_Instr_Reg_Pop_Word2
);
2458 else if( stmt
->c3
->type
->size
== 4 )
2459 emit
->append( new Chuck_Instr_Reg_Pop_Word
);
2460 else if( stmt
->c3
->type
->size
!= 0 )
2462 EM_error2( stmt
->c3
->linepos
,
2463 "(emit): internal error: non-void type size %i not handled",
2464 stmt
->c3
->type
->size
);
2468 // go back to do check the condition
2469 emit
->append( new Chuck_Instr_Goto( start_index
) );
2473 // set the op's target
2474 op
->set( emit
->next_index() );
2482 //------------------------------------------------------------------------------
2483 // name: emit_engine_emit_if()
2485 //------------------------------------------------------------------------------
2486 t_CKBOOL
emit_engine_emit_if( Chuck_Emmission
* emit
, a_Stmt_If stmt
)
2488 t_CKBOOL ret
= TRUE
;
2489 Chuck_Instr_Branch_Op
* op
= NULL
, * op2
= NULL
;
2490 uint start_index
= emit
->next_index();
2493 emit_engine_emit_exp( emit
, stmt
->cond
);
2495 switch( stmt
->cond
->type
->type
)
2500 emit
->append( new Chuck_Instr_Reg_Push_Imm( 0 ) );
2501 op
= new Chuck_Instr_Branch_Eq_uint( 0 );
2507 emit
->append( new Chuck_Instr_Reg_Push_Imm2( 0.0 ) );
2508 op
= new Chuck_Instr_Branch_Eq_double( 0 );
2512 EM_error2( stmt
->cond
->linepos
,
2513 "(emit): internal erorr: unhandled type '%s' in if conditional",
2514 stmt
->cond
->type
->name
);
2522 emit_engine_emit_stmt( emit
, stmt
->if_body
);
2524 // emit the skip to the end
2525 emit
->append( op2
= new Chuck_Instr_Goto(0) );
2527 // set the op's target
2528 op
->set( emit
->next_index() );
2531 emit_engine_emit_stmt( emit
, stmt
->else_body
);
2533 // set the op2's target
2534 op2
->set( emit
->next_index() );
2542 //------------------------------------------------------------------------------
2543 // name: emit_engine_emit_return()
2545 //------------------------------------------------------------------------------
2546 t_CKBOOL
emit_engine_emit_return( Chuck_Emmission
* emit
, a_Stmt_Return ret
)
2548 if( !emit_engine_emit_exp( emit
, ret
->val
) )
2551 // determine where later
2552 Chuck_Instr_Goto
* instr
= new Chuck_Instr_Goto( 0 );
2553 emit
->append( instr
);
2554 emit
->returns
.push_back( instr
);
2562 //------------------------------------------------------------------------------
2563 // name: emit_engine_emit_code_segment()
2565 //------------------------------------------------------------------------------
2566 t_CKBOOL
emit_engine_emit_code_segment( Chuck_Emmission
* emit
, a_Stmt_Code stmt
)
2568 a_Stmt_List list
= stmt
->stmt_list
;
2572 if( !emit_engine_emit_stmt( emit
, list
->stmt
) )
2584 //-----------------------------------------------------------------------------
2585 // name: emit_engine_emit_chuck()
2586 // desc: emit chuck operator
2587 //-----------------------------------------------------------------------------
2588 t_CKBOOL
emit_engine_emit_chuck( Chuck_Emmission
* emit
, a_Exp lhs
, a_Exp rhs
)
2590 if( rhs
->type
->type
== te_midiout
|| lhs
->type
->type
== te_midiin
)
2591 emit
->pop_the_ops();
2593 if( lhs
->type
->parent
&& rhs
->type
->parent
&&
2594 lhs
->type
->parent
->type
== te_ugen
&&
2595 rhs
->type
->parent
->type
== te_ugen
)
2597 emit
->append( new Chuck_Instr_UGen_Link
);
2601 else if( lhs
->type
->type
== __te_system_out__
)
2603 switch( rhs
->type
->type
)
2606 emit
->append( new Chuck_Instr_Reg_Push_Imm( cip_int
) );
2609 emit
->append( new Chuck_Instr_Reg_Push_Imm( cip_uint
) );
2612 emit
->append( new Chuck_Instr_Reg_Push_Imm( cip_float
) );
2615 emit
->append( new Chuck_Instr_Reg_Push_Imm( cip_double
) );
2618 emit
->append( new Chuck_Instr_Reg_Push_Imm( cip_time
) );
2621 emit
->append( new Chuck_Instr_Reg_Push_Imm( cip_dur
) );
2624 emit
->append( new Chuck_Instr_Reg_Push_Imm( cip_string
) );
2627 EM_error2( rhs
->linepos
,
2628 "(emit): internal error: unsupported type '%s' to print to console",
2633 emit
->append( new Chuck_Instr_Print_Console2
);
2635 else if( rhs
->s_type
!= ae_exp_decl
)
2637 if( rhs
->s_type
== ae_exp_primary
&&
2638 rhs
->primary
.s_type
== ae_primary_var
)
2640 a_Exp_Primary primary
= &(rhs
->primary
);
2641 if( !strcmp( S_name(primary
->var
), "now" ) )
2643 // special case: time advance
2644 if( lhs
->type
->type
== te_dur
)
2645 emit
->append( new Chuck_Instr_Add_dur_time
);
2646 else if( lhs
->type
->type
== te_time
)
2647 // pop the now - no need it anymore
2648 emit
->append( new Chuck_Instr_Reg_Pop_Word2() );
2651 EM_error2( lhs
->linepos
,
2652 "(emit): internal error: bad type '%s' chucked to now",
2658 emit
->append( new Chuck_Instr_Time_Advance
);
2662 else if( !strcmp( S_name(primary
->var
), "midiin" ) )
2664 EM_error2( lhs
->linepos
,
2665 "(emit): internal error: value chucked to midiin" );
2668 else if( !strcmp( S_name(primary
->var
), "midiout" ) )
2671 // emit->append( new Chuck_Instr_Midi_Out_Go(0) );
2674 else if( !strcmp( S_name(primary
->var
), "true" ) )
2676 EM_error2( primary
->linepos
,
2677 "cannot assign value to 'true'" );
2680 else if( !strcmp( S_name(primary
->var
), "false" ) )
2682 EM_error2( primary
->linepos
,
2683 "cannot assign value to 'false'" );
2686 else if( !strcmp( S_name(primary
->var
), "maybe" ) )
2688 EM_error2( primary
->linepos
,
2689 "cannot assign value to 'maybe'" );
2692 else if( !strcmp( S_name(primary
->var
), "pi" ) )
2694 EM_error2( primary
->linepos
,
2695 "cannot assign value to 'pi'" );
2698 else if( !strcmp( S_name(primary
->var
), "stdout" ) ||
2699 !strcmp( S_name(primary
->var
), "chout" ) )
2701 switch( lhs
->type
->type
)
2704 emit
->append( new Chuck_Instr_Reg_Push_Imm( cip_int
) );
2707 emit
->append( new Chuck_Instr_Reg_Push_Imm( cip_uint
) );
2710 emit
->append( new Chuck_Instr_Reg_Push_Imm( cip_double
) );
2713 emit
->append( new Chuck_Instr_Reg_Push_Imm( cip_double
) );
2716 emit
->append( new Chuck_Instr_Reg_Push_Imm( cip_time
) );
2719 emit
->append( new Chuck_Instr_Reg_Push_Imm( cip_dur
) );
2722 emit
->append( new Chuck_Instr_Reg_Push_Imm( cip_string
) );
2725 EM_error2( lhs
->linepos
,
2726 "(emit): internal error: unsupported type '%s' to print to console",
2731 emit
->append( new Chuck_Instr_Print_Console
);
2735 t_CKUINT is_global
= FALSE
;
2737 int offset
= emit
->find_offset( primary
->var
, &is_global
, &size
);
2738 Chuck_Instr_Unary_Op
* op
= NULL
;
2742 // should be a function
2743 EM_error2( rhs
->linepos
,
2744 "(emit): internal error: chuck to function not impl" );
2749 // TODO: fix this hack
2751 emit
->append( new Chuck_Instr_Reg_Pop_Word
);
2752 else if( size
== 8 )
2753 emit
->append( new Chuck_Instr_Reg_Pop_Word2
);
2756 EM_error2( rhs
->linepos
,
2757 "(emit): %i byte not handled in chuck operator : decl",
2762 emit
->append( op
= new Chuck_Instr_Reg_Push_Imm( offset
) );
2763 if( emit
->is_global
|| !is_global
)
2765 // special case: assignment
2766 if( rhs
->type
->parent
== NULL
)
2768 if( rhs
->type
->size
== 4 )
2769 emit
->append( new Chuck_Instr_Chuck_Assign
);
2770 else if( rhs
->type
->size
== 8 )
2771 emit
->append( new Chuck_Instr_Chuck_Assign2
);
2774 EM_error2( rhs
->linepos
,
2775 "(emit): %i byte not handled in chuck operator assign",
2781 emit
->append( new Chuck_Instr_Chuck_Assign_Object
);
2785 emit
->addr_map
.push_back( op
);
2786 // special case: deref assignment
2787 if( rhs
->type
->parent
== NULL
)
2789 if( rhs
->type
->size
== 4 )
2790 emit
->append( new Chuck_Instr_Chuck_Assign_Deref
);
2792 emit
->append( new Chuck_Instr_Chuck_Assign_Deref2
);
2795 emit
->append( new Chuck_Instr_Chuck_Assign_Object_Deref
);
2800 else if( rhs
->s_type
== ae_exp_namespace
)
2802 if( lhs
->type
->type
== te_string
)
2804 // emit instruction to load the DLL
2805 emit
->append( new Chuck_Instr_DLL_Load
);
2809 EM_error2( lhs
->linepos
,
2810 "(emit): internal error: unhandled type '%s' in namespace expression",
2815 else if( rhs
->s_type
== ae_exp_dot_member
&& rhs
->dot_member
.data
)
2817 // the function addr
2818 emit
->append( new Chuck_Instr_Reg_Push_Imm( rhs
->dot_member
.data
) );
2819 emit
->append( new Chuck_Instr_Reg_Push_Imm( rhs
->dot_member
.data2
) );
2822 if( !strcmp( S_name(rhs
->dot_member
.id
), "op" ) )
2823 emit
->append( new Chuck_Instr_UGen_Ctrl_Op
);
2824 else if( !strcmp( S_name(rhs
->dot_member
.id
), "gain" ) )
2825 emit
->append( new Chuck_Instr_UGen_Ctrl_Gain
);
2826 else if( !strcmp( S_name(rhs
->dot_member
.id
), "last" ) )
2828 EM_error2( rhs
->linepos
,
2829 "(emit): internal error: cannot chuck to 'ugen.last'" );
2834 // ctrl passing to ugen
2835 if( rhs
->type
->size
== 4 )
2836 emit
->append( new Chuck_Instr_UGen_Ctrl
);
2837 else if( rhs
->type
->size
== 8 )
2838 emit
->append( new Chuck_Instr_UGen_Ctrl2
);
2841 EM_error2( rhs
->linepos
,
2842 "(emit): internal error: %i ugen ctrl not handled",
2848 else if( rhs
->s_type
== ae_exp_dot_member
)
2850 EM_error2( rhs
->linepos
,
2851 "(emit): cannot assign values to namespace constants" );
2856 EM_error2( rhs
->linepos
,
2857 "(emit): internal error: illegal expression" );
2861 else // if( rhs->s_type == ae_exp_decl )
2863 // special case: assignment
2864 if( rhs
->type
->parent
== NULL
)
2866 if( rhs
->type
->size
== 4 )
2867 emit
->append( new Chuck_Instr_Chuck_Assign
);
2868 else if( rhs
->type
->size
== 8 )
2869 emit
->append( new Chuck_Instr_Chuck_Assign2
);
2872 EM_error2( rhs
->linepos
,
2873 "(emit): %i size not handled in chuck assigg",
2879 emit
->append( new Chuck_Instr_Chuck_Assign_Object
);
2888 //-----------------------------------------------------------------------------
2889 // name: emit_engine_emit_unchuck()
2891 //-----------------------------------------------------------------------------
2892 t_CKBOOL
emit_engine_emit_unchuck( Chuck_Emmission
* emit
, a_Exp lhs
, a_Exp rhs
)
2894 if( lhs
->type
->parent
&& rhs
->type
->parent
&&
2895 lhs
->type
->parent
->type
== te_ugen
&& rhs
->type
->parent
->type
== te_ugen
)
2897 emit
->append( new Chuck_Instr_UGen_UnLink
);
2901 EM_error2( lhs
->linepos
,
2902 "(emit): internal error: no suitable un-chuck resolution on types '%s' and '%s'",
2903 lhs
->type
->name
, rhs
->type
->name
);
2913 //-----------------------------------------------------------------------------
2914 // name: emit_engine_emit_func_def()
2916 //-----------------------------------------------------------------------------
2917 t_CKBOOL
emit_engine_emit_func_def( Chuck_Emmission
* emit
, a_Func_Def func_def
)
2919 if( func_def
->s_type
== ae_func_user
)
2921 emit
->is_global
= FALSE
;
2922 emit
->local
= new Chuck_Code( S_name(func_def
->name
) );
2923 emit
->push( "__func_def_scope__" );
2924 emit
->functions
.push_back( emit
->local
);
2925 emit
->local
->stack_depth
= func_def
->stack_depth
;
2926 emit
->returns
.clear();
2929 a_Arg_List args
= func_def
->arg_list
;
2933 emit
->alloc_local( args
->id
, args
->type
);
2937 // emit the function body
2938 emit_engine_emit_stmt( emit
, func_def
->code
);
2940 // return index to the end of the function
2941 for( unsigned int i
= 0; i
< emit
->returns
.size(); i
++ )
2942 emit
->returns
[i
]->set( emit
->next_index() );
2945 emit
->append( new Chuck_Instr_Func_Return
);
2948 emit
->is_global
= TRUE
;
2953 EM_error2( func_def
->linepos
,
2954 "(emit): internal error: builtin functions not impl" );
2963 //-----------------------------------------------------------------------------
2964 // name: emit_engine_emit_exp_mem()
2965 // desc: emit an exp as memory address only
2966 //-----------------------------------------------------------------------------
2967 t_CKBOOL
emit_engine_emit_exp_mem( Chuck_Emmission
* emit
, a_Exp exp
)
2971 switch( exp
->s_type
)
2973 case ae_exp_primary
:
2974 if( !emit_engine_emit_exp_primary_mem( emit
, &exp
->primary
) )
2978 case ae_exp_dot_member
:
2979 if( !emit_engine_emit_exp_dot_member_mem( emit
, &exp
->dot_member
) )
2984 if( !emit_engine_emit_exp_array_mem( emit
, &exp
->array
) )
2988 case ae_exp_func_call
:
2989 if( !emit_engine_emit_exp_func_call_mem( emit
, &exp
->func_call
) )
2994 EM_error2( exp
->linepos
,
2995 "(emit): internal error: unhandled expression in [mem] emission" );
3008 //-----------------------------------------------------------------------------
3009 // name: emit_engine_emit_exp_primary_mem()
3010 // desc: emit a primary exp as memory address only
3011 //-----------------------------------------------------------------------------
3012 t_CKBOOL
emit_engine_emit_exp_primary_mem( Chuck_Emmission
* emit
, a_Exp_Primary exp
)
3014 switch( exp
->s_type
)
3016 case ae_primary_var
:
3017 /*if( exp->var == insert_symbol( "now" ) )
3019 emit->append( new Chuck_Instr_Reg_Push_Now );
3023 int offset
= emit
->find_offset( exp
->var
);
3026 // could be a function
3027 EM_error2( exp
->linepos
,
3028 "(emit): internal error: cannot resolve [mem] var '%s'",
3033 emit
->append( new Chuck_Instr_Reg_Push_Imm( offset
) );
3037 case ae_primary_exp
:
3038 return emit_engine_emit_exp_mem( emit
, exp
->exp
);
3042 EM_error2( exp
->linepos
,
3043 "(emit): internal error: cannot emit [mem] primary exp" );
3053 //-----------------------------------------------------------------------------
3054 // name: emit_engine_emit_exp_dot_member_mem()
3055 // desc: emit a dot exp as memory address only
3056 //-----------------------------------------------------------------------------
3057 t_CKBOOL
emit_engine_emit_exp_dot_member_mem( Chuck_Emmission
* emit
, a_Exp_Dot_Member exp
)
3059 EM_error2( exp
->linepos
,
3060 "(emit): internal erorr: . address not impl" );
3067 //-----------------------------------------------------------------------------
3068 // name: emit_engine_emit_exp_array_mem()
3069 // desc: emit array exp as memory address only
3070 //-----------------------------------------------------------------------------
3071 t_CKBOOL
emit_engine_emit_exp_array_mem( Chuck_Emmission
* emit
, a_Exp_Array exp
)
3073 EM_error2( exp
->linepos
,
3074 "(emit): internal error: array address not impl" );
3081 //-----------------------------------------------------------------------------
3082 // name: emit_engine_emit_exp_func_call_mem()
3083 // desc: emit a func call exp as memory address only
3084 //-----------------------------------------------------------------------------
3085 t_CKBOOL
emit_engine_emit_exp_func_call_mem( Chuck_Emmission
* emit
, a_Exp_Func_Call exp
)
3087 EM_error2( exp
->linepos
,
3088 "(emit): internal error: func call address no impl" );