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_types.cpp
29 // author: Ge Wang (gewang@cs.princeton.edu)
30 // Perry R. Cook (prc@cs.princeton.edu)
32 //-----------------------------------------------------------------------------
39 #include "chuck_type.h"
40 #include "chuck_instr.h"
43 #include "chuck_errmsg.h"
44 #include "chuck_symbol.h"
49 //-----------------------------------------------------------------------------
50 // name: struct t_Env_
51 // desc: type check env
52 //-----------------------------------------------------------------------------
65 vector
<map
<S_Symbol
, S_Symbol
> *> scope
;
71 map
<Chuck_DLL
*, bool> dlls
;
81 t_Env_() { this->scope_push(); }
82 ~t_Env_() { this->scope_pop(); }
85 { scope
.push_back( new map
<S_Symbol
, S_Symbol
> ); }
87 { if( scope
.size() ) { delete scope
.back(); scope
.pop_back(); } }
88 void scope_add( S_Symbol id
)
89 { assert( scope
.size() ); (*scope
.back())[id
] = id
; }
90 t_CKBOOL
scope_lookup( S_Symbol id
)
91 { assert( scope
.size() ); return (*scope
.back())[id
] != NULL
; }
97 //-----------------------------------------------------------------------------
98 // name: struct t_Class_Info_
100 //-----------------------------------------------------------------------------
105 vector
<t_Type
> fields
;
106 vector
<a_Func_Def
> funcs
;
109 t_Class_Info_() { type
= NULL
; }
116 struct t_Type_ t_void
= { te_void
, "void", NULL
, 0 };
117 struct t_Type_ t_int
= { te_int
, "int", NULL
, sizeof(t_CKINT
) };
118 struct t_Type_ t_uint
= { te_uint
, "uint", NULL
, sizeof(t_CKUINT
) };
119 // NOTE: float is single
120 struct t_Type_ t_single
= { te_single
, "single", NULL
, sizeof(float) };
121 struct t_Type_ t_float
= { te_float
, "float", NULL
, sizeof(double) };
122 struct t_Type_ t_double
= { te_double
, "double", NULL
, sizeof(double) };
123 // note hard code in the next two lines
124 struct t_Type_ t_time
= { te_time
, "time", NULL
, sizeof(t_CKTIME
) };
125 struct t_Type_ t_dur
= { te_dur
, "dur", NULL
, sizeof(t_CKTIME
) };
126 struct t_Type_ t_function
= { te_function
, "function", NULL
, sizeof(void *) };
127 struct t_Type_ t_null
= { te_null
, "NULL", NULL
, sizeof(void *) };
128 struct t_Type_ t_unit
= { te_unit
, "()", NULL
, sizeof(int) };
129 struct t_Type_ t_code
= { te_code
, "code", NULL
, sizeof(void *) };
130 struct t_Type_ t_object
= { te_object
, "object", NULL
, sizeof(void *) };
131 struct t_Type_ t_class
= { te_class
, "class", NULL
, sizeof(void *) };
132 struct t_Type_ t_array
= { te_array
, "array", NULL
, sizeof(void *) };
133 struct t_Type_ t_tuple
= { te_tuple
, "tuple", NULL
, sizeof(void *) };
134 struct t_Type_ t_string
= { te_string
, "string", NULL
, sizeof(void *) };
135 struct t_Type_ t_pattern
= { te_pattern
, "pattern", &t_object
, sizeof(void *) };
136 struct t_Type_ t_thread
= { te_thread
, "thread", &t_object
, sizeof(void *) };
137 struct t_Type_ t_shred
= { te_shred
, "shred", &t_object
, sizeof(void *) };
138 struct t_Type_ t_ugen
= { te_ugen
, "ugen", &t_object
, sizeof(void *) };
139 struct t_Type_ t_transport
= { te_transport
, "transport", &t_object
, sizeof(void *) };
140 struct t_Type_ t_host
= { te_host
, "host", &t_object
, sizeof(void *) };
141 struct t_Type_ t_midiout
= { te_midiout
, "midiout", &t_object
, sizeof(void *) };
142 struct t_Type_ t_midiin
= { te_midiin
, "midiin", &t_object
, sizeof(void *) };
143 struct t_Type_ t_adc
= { te_adc
, "adc", &t_ugen
, t_ugen
.size
};
144 struct t_Type_ t_dac
= { te_dac
, "dac", &t_ugen
, t_ugen
.size
};
145 struct t_Type_ t_bunghole
= { te_bunghole
, "bunghole", &t_ugen
, t_ugen
.size
};
148 // system types (internal - cannot instantiate)
149 struct t_Type_ t_system_time
=
150 { __te_system_time__
, "@__system_time__", &t_object
, sizeof(void *) };
151 struct t_Type_ t_system_out
=
152 { __te_system_out__
, "@__system_out__", &t_object
, sizeof(void *) };
153 struct t_Type_ t_system_err
=
154 { __te_system_err__
, "@__system_err__", &t_object
, sizeof(void *) };
155 struct t_Type_ t_system_namespace
=
156 { __te_system_namespace__
, "@__system_namespace__", NULL
, sizeof(void *) };
160 t_Env
type_engine_init();
161 t_CKBOOL
type_engine_shutdown( t_Env env
);
162 t_CKBOOL
type_engine_check_prog( t_Env env
, a_Program prog
);
163 t_CKBOOL
type_engine_check_func_def( t_Env env
, a_Func_Def func_def
);
164 t_CKBOOL
type_engine_check_func_def_import( t_Env nspc
, a_Func_Def func_def
);
165 t_CKBOOL
type_engine_check_ugen_def_import( t_Env nspc
, Chuck_UGen_Info
* ugen
);
166 t_CKBOOL
type_engine_check_value_import( t_Env nspc
, S_Symbol name
, S_Symbol type
, void * addr
);
167 t_CKBOOL
type_engine_check_stmt_list( t_Env env
, a_Stmt_List list
);
168 t_CKBOOL
type_engine_check_stmt( t_Env env
, a_Stmt stmt
);
169 t_Type
type_engine_check_exp( t_Env env
, a_Exp exp
);
170 t_Type
type_engine_check_primary( t_Env env
, a_Exp_Primary exp
);
171 t_Type
type_engine_check_op( t_Env env
, ae_Operator op
,
172 t_Type left
, t_Type right
);
173 t_Type
type_engine_check_exp_binary( t_Env env
, a_Exp_Binary binary
);
174 t_Type
type_engine_check_exp_unary( t_Env env
, a_Exp_Unary unary
);
175 t_Type
type_engine_check_exp_cast( t_Env env
, a_Exp_Cast cast
);
176 t_Type
type_engine_check_exp_postfix( t_Env env
, a_Exp_Postfix postfix
);
177 t_Type
type_engine_check_exp_dur( t_Env env
, a_Exp_Dur dur
);
178 t_Type
type_engine_check_exp_array( t_Env env
, a_Exp_Array array
);
179 t_Type
type_engine_check_exp_func_call( t_Env env
, a_Exp_Func_Call func_call
);
180 t_Type
type_engine_check_exp_dot_member( t_Env env
, a_Exp_Dot_Member member
);
181 t_Type
type_engine_check_exp_if( t_Env env
, a_Exp_If exp_if
);
182 t_Type
type_engine_check_exp_decl( t_Env env
, a_Exp_Decl decl
);
183 t_Type
type_engine_check_exp_namespace( t_Env env
, a_Exp_Namespace name_space
);
184 t_CKBOOL
type_engine_check_if( t_Env env
, a_Stmt_If stmt
);
185 t_CKBOOL
type_engine_check_for( t_Env env
, a_Stmt_For stmt
);
186 t_CKBOOL
type_engine_check_code_segment( t_Env env
, a_Stmt_Code stmt
);
187 t_CKBOOL
type_engine_check_while( t_Env env
, a_Stmt_While stmt
);
188 t_CKBOOL
type_engine_check_until( t_Env env
, a_Stmt_Until stmt
);
189 t_CKBOOL
type_engine_check_switch( t_Env env
, a_Stmt_Switch stmt
);
190 t_CKBOOL
type_engine_check_return( t_Env env
, a_Stmt_Return stmt
);
191 t_CKBOOL
type_engine_check_cast_valid( t_Env env
, t_Type to
, t_Type from
);
193 t_CKBOOL
type_engine_check_exp_mem( t_Env env
, a_Exp exp
);
194 t_CKBOOL
type_engine_check_primary_mem( t_Env env
, a_Exp_Primary exp
);
195 t_CKBOOL
type_engine_check_exp_dot_member_mem( t_Env env
, a_Exp_Dot_Member member
);
196 t_CKBOOL
type_engine_check_exp_array_mem( t_Env env
, a_Exp_Array array
);
197 t_CKBOOL
type_engine_check_exp_func_call_mem( t_Env env
, a_Exp_Func_Call func_call
);
200 t_Type
make_type( const char * name
, t_Type parent
, unsigned int size
)
202 t_Type t
= (t_Type
)checked_malloc(sizeof(struct t_Type_
));
203 t
->type
= __te_system_user__
;
204 t
->name
= (char *)checked_malloc(strlen(name
)+1);
205 strcpy( t
->name
, name
);
214 t_Type
dup_type( t_Type type
)
216 t_Type t
= make_type( type
->name
, type
->parent
, type
->size
);
217 t
->type
= type
->type
;
222 t_CKBOOL
isa( t_Type a
, t_Type b
)
224 if( !a
|| !b
) return FALSE
;
225 if( a
->type
!= __te_system_user__
)
226 if( a
->type
== b
->type
) return TRUE
;
228 if( !strcmp( a
->name
, b
->name
) ) return TRUE
;
229 return isa( a
->parent
, b
);
234 //-----------------------------------------------------------------------------
235 // name: new_namespace()
236 // desc: initialize a namespace
237 //-----------------------------------------------------------------------------
238 t_Env
new_namespace( const char * name
, t_Env parent
, unsigned size
)
240 // allocate a new env
241 t_Env e
= new t_Env_
;
244 e
->type
= S_empty2( size
);
245 e
->value
= S_empty2( size
);
246 e
->function
= S_empty2( size
);
247 e
->ugen
= S_empty2( size
);
248 e
->name_space
= S_empty2( size
);
249 e
->addr
= S_empty2( size
);
250 e
->name
= insert_symbol( name
);
252 e
->vm
= ( parent
? parent
->vm
: NULL
);
253 e
->is_class
= FALSE
; // this is a namespace
268 //-----------------------------------------------------------------------------
269 // name: type_engine_init()
270 // desc: initialize a type engine
271 //-----------------------------------------------------------------------------
272 t_Env
type_engine_init( Chuck_VM
* vm
)
274 // allocate a new env
275 t_Env e
= new_namespace( "global", NULL
, 65437 );
278 // enter the type mapping
279 S_enter( e
->type
, insert_symbol(t_void
.name
), &t_void
);
280 S_enter( e
->type
, insert_symbol(t_int
.name
), &t_int
);
281 S_enter( e
->type
, insert_symbol(t_uint
.name
), &t_uint
);
282 S_enter( e
->type
, insert_symbol(t_float
.name
), &t_float
);
283 S_enter( e
->type
, insert_symbol(t_time
.name
), &t_time
);
284 S_enter( e
->type
, insert_symbol(t_dur
.name
), &t_dur
);
285 S_enter( e
->type
, insert_symbol(t_function
.name
), &t_function
);
286 S_enter( e
->type
, insert_symbol(t_null
.name
), &t_null
);
287 S_enter( e
->type
, insert_symbol(t_unit
.name
), &t_unit
);
288 S_enter( e
->type
, insert_symbol(t_code
.name
), &t_code
);
289 S_enter( e
->type
, insert_symbol(t_object
.name
), &t_object
);
290 S_enter( e
->type
, insert_symbol(t_class
.name
), &t_class
);
291 S_enter( e
->type
, insert_symbol(t_array
.name
), &t_array
);
292 S_enter( e
->type
, insert_symbol(t_tuple
.name
), &t_tuple
);
293 S_enter( e
->type
, insert_symbol(t_string
.name
), &t_string
);
294 S_enter( e
->type
, insert_symbol(t_pattern
.name
), &t_pattern
);
295 S_enter( e
->type
, insert_symbol(t_thread
.name
), &t_thread
);
296 S_enter( e
->type
, insert_symbol(t_shred
.name
), &t_shred
);
297 S_enter( e
->type
, insert_symbol(t_transport
.name
), &t_transport
);
298 S_enter( e
->type
, insert_symbol(t_host
.name
), &t_host
);
299 S_enter( e
->type
, insert_symbol(t_midiout
.name
), &t_midiout
);
300 S_enter( e
->type
, insert_symbol(t_midiin
.name
), &t_midiin
);
301 S_enter( e
->type
, insert_symbol(t_ugen
.name
), &t_ugen
);
302 // S_enter( e->type, insert_symbol(t_adc.name), &t_adc );
303 // S_enter( e->type, insert_symbol(t_dac.name), &t_dac );
306 S_enter( e
->value
, insert_symbol( "null" ), &t_null
);
308 S_enter( e
->value
, insert_symbol( "now" ), &t_time
);
309 S_enter( e
->value
, insert_symbol( "start" ), &t_time
);
311 S_enter( e
->value
, insert_symbol( "samp" ), &t_dur
);
312 S_enter( e
->value
, insert_symbol( "ms" ), &t_dur
);
313 S_enter( e
->value
, insert_symbol( "second" ), &t_dur
);
314 S_enter( e
->value
, insert_symbol( "minute" ), &t_dur
);
315 S_enter( e
->value
, insert_symbol( "hour" ), &t_dur
);
316 S_enter( e
->value
, insert_symbol( "day" ), &t_dur
);
317 S_enter( e
->value
, insert_symbol( "week" ), &t_dur
);
319 S_enter( e
->value
, insert_symbol( "language" ), &t_null
);
320 S_enter( e
->value
, insert_symbol( "compiler" ), &t_null
);
321 S_enter( e
->value
, insert_symbol( "machine" ), &t_null
);
323 S_enter( e
->value
, insert_symbol( "chout" ), &t_system_out
);
324 S_enter( e
->value
, insert_symbol( "cherr" ), &t_system_err
);
325 S_enter( e
->value
, insert_symbol( "stdout" ), &t_system_out
);
326 S_enter( e
->value
, insert_symbol( "stderr" ), &t_system_err
);
327 S_enter( e
->value
, insert_symbol( "midiout" ), &t_midiout
);
328 S_enter( e
->value
, insert_symbol( "midiin" ), &t_midiin
);
329 S_enter( e
->value
, insert_symbol( "adc" ), &t_adc
);
330 S_enter( e
->value
, insert_symbol( "dac" ), &t_dac
);
331 S_enter( e
->value
, insert_symbol( "bunghole" ), &t_bunghole
);
332 S_enter( e
->value
, insert_symbol( "blackhole" ), &t_bunghole
);
334 S_enter( e
->value
, insert_symbol( "true" ), &t_int
);
335 S_enter( e
->value
, insert_symbol( "false" ), &t_int
);
336 S_enter( e
->value
, insert_symbol( "maybe" ), &t_int
);
337 S_enter( e
->value
, insert_symbol( "pi" ), &t_float
);
338 S_enter( e
->value
, insert_symbol( "endl" ), &t_string
);
341 S_enter( e
->value
, insert_symbol( "global" ), &t_system_namespace
);
342 S_enter( e
->name_space
, insert_symbol( "global" ), e
);
350 //-----------------------------------------------------------------------------
351 // name: do_make_args()
353 //-----------------------------------------------------------------------------
354 a_Arg_List
do_make_args( const vector
<Chuck_Info_Param
> & params
, unsigned int index
)
356 a_Arg_List args
= NULL
;
357 if( index
>= params
.size() )
360 if( index
== (params
.size()-1) )
361 args
= new_arg_list( new_type_decl( (char*)params
[index
].type
.c_str(), 0 ),
362 (char*)params
[index
].name
.c_str(), 0 );
364 args
= prepend_arg_list(
365 new_type_decl( (char*)params
[index
].type
.c_str(), 0 ),
366 (char*)params
[index
].name
.c_str(),
367 do_make_args( params
, index
+ 1 ), 0 );
373 UGEN_CTRL
ugen_ctrl_op( t_CKTIME now
, void * data
, void * value
) { }
374 UGEN_CGET
ugen_cget_op( t_CKTIME now
, void * data
, void * out
) { }
377 UGEN_CTRL
ugen_ctrl_gain( t_CKTIME now
, void * data
, void * value
) { }
378 UGEN_CGET
ugen_cget_gain( t_CKTIME now
, void * data
, void * out
) { }
381 UGEN_CGET
ugen_cget_last( t_CKTIME now
, void * data
, void * out
) { }
384 //-----------------------------------------------------------------------------
385 // name: type_engine_add_dll()
387 //-----------------------------------------------------------------------------
388 t_CKBOOL
type_engine_add_dll( t_Env env
, Chuck_DLL
* dll
, const char * nspc
)
390 // lookup the namesapce
391 t_Env info
= (t_Env
)S_look( env
->name_space
,
392 insert_symbol( (char *)nspc
) );
394 if( info
&& info
->dlls
[dll
] )
399 info
= new_namespace( nspc
, env
, 211 );
400 S_enter( env
->value
, insert_symbol(nspc
), &t_system_namespace
);
401 env
->scope_add( insert_symbol(nspc
) );
402 S_enter( env
->name_space
, insert_symbol(nspc
), info
);
405 // add all the prototypes
406 Chuck_DL_Query
* query
= (Chuck_DL_Query
*)dll
->query();
407 for( unsigned int i
= 0; i
< query
->dll_exports
.size(); i
++ )
410 Chuck_DL_Proto
* proto
= &query
->dll_exports
[i
];
416 a_Type_Decl rtype
= new_type_decl( (char *)proto
->type
.c_str(), 0 );
418 a_Arg_List args
= NULL
;
419 if( proto
->params
.size() )
420 args
= do_make_args( proto
->params
, 0 );
421 // allocate a new function
422 a_Func_Def func
= new_func_def(
423 ae_func_func
, rtype
, (char*)proto
->name
.c_str(), args
, NULL
, 0 );
425 func
->builtin
= (builtin_func_ptr
)proto
->addr
;
426 func
->linepos
= query
->linepos
;
428 if( !type_engine_check_func_def_import( info
, func
) )
431 info
->dlls
.erase( dll
);
438 if( !type_engine_check_value_import( info
,
439 insert_symbol((char *)proto
->name
.c_str()),
440 insert_symbol((char *)proto
->type
.c_str()),
441 (void *)proto
->addr
) )
443 info
->dlls
.erase( dll
);
449 // add the unit generators
450 for( unsigned int j
= 0; j
< query
->ugen_exports
.size(); j
++ )
452 Chuck_UGen_Info
* ugen
= new Chuck_UGen_Info( query
->ugen_exports
[j
] );
454 if( !type_engine_check_ugen_def_import( env
, ugen
) )
457 // info->dlls.erase( dll );
463 info
->dlls
[dll
] = true;
472 //-----------------------------------------------------------------------------
473 // name: type_engine_shutdown()
474 // desc: shutdown a type engine
475 //-----------------------------------------------------------------------------
476 t_CKBOOL
type_engine_shutdown( t_Env env
)
479 if( env
->type
) free( env
->type
);
480 if( env
->value
) free( env
->value
);
481 if( env
->function
) free( env
->function
);
482 if( env
->ugen
) free( env
->ugen
);
483 if( env
->name_space
) free( env
->name_space
);
493 //-----------------------------------------------------------------------------
494 // name: type_engine_check_prog()
495 // desc: type check a program
496 //-----------------------------------------------------------------------------
497 t_CKBOOL
type_engine_check_prog( t_Env env
, a_Program prog
)
506 switch( prog
->section
->s_type
)
508 case ae_section_stmt
:
509 ret
= type_engine_check_stmt_list( env
, prog
->section
->stmt_list
);
512 case ae_section_func
:
513 ret
= type_engine_check_func_def( env
, prog
->section
->func_def
);
516 case ae_section_class
:
517 EM_error2( prog
->linepos
, "class def not impl!" );
531 //-----------------------------------------------------------------------------
532 // name: type_engine_begin() type_engine_end()
534 //-----------------------------------------------------------------------------
535 void type_engine_begin( t_Env env
)
536 { S_beginScope( env
->value
); env
->scope_push(); }
537 void type_engine_end( t_Env env
)
538 { S_endScope( env
->value
); env
->scope_pop(); }
543 //-----------------------------------------------------------------------------
544 // name: type_engine_check_func_def()
546 //-----------------------------------------------------------------------------
547 t_CKBOOL
type_engine_check_func_def( t_Env env
, a_Func_Def f
)
550 if( S_look( env
->value
, f
->name
) )
552 EM_error2( f
->linepos
,
553 "function name '%s' is already used by another value", S_name(f
->name
) );
557 // enter the name into the value table
558 S_enter( env
->value
, f
->name
, &t_function
);
559 env
->scope_add( f
->name
);
560 // enter the name into the function table
561 S_enter( env
->function
, f
->name
, f
);
563 f
->s_type
= ae_func_user
;
566 S_beginScope( env
->value
);
569 env
->is_global
= FALSE
;
573 // make room for return address and pc
574 S_enter( env
->value
, insert_symbol( "@__pc__" ), &t_uint
);
575 S_enter( env
->value
, insert_symbol( "@__mem_sp__" ), &t_uint
);
577 // look up the return type
578 f
->ret_type
= (t_Type
)S_look( env
->type
, f
->type_decl
->id
);
582 EM_error2( f
->linepos
, "for function '%s':", S_name(f
->name
) );
583 EM_error2( f
->linepos
, "undefined return type '%s'", S_name(f
->type_decl
->id
) );
586 // f->ret_type->array_depth = f->type_decl->array;
588 a_Arg_List arg_list
= f
->arg_list
;
589 unsigned int count
= 1;
594 // look up in type table
595 arg_list
->type
= (t_Type
)S_look( env
->type
, arg_list
->type_decl
->id
);
596 if( !arg_list
->type
)
598 EM_error2( arg_list
->linepos
, "in function '%s':", S_name(f
->name
) );
599 EM_error2( arg_list
->linepos
, "argument %i '%s' has undefined type '%s'",
600 count
, S_name(arg_list
->id
), S_name(arg_list
->type_decl
->id
) );
605 if( env
->scope_lookup( arg_list
->id
) )
607 EM_error2( arg_list
->linepos
, "in function '%s':", S_name(f
->name
) );
608 EM_error2( arg_list
->linepos
, "argument %i '%s' is already defined in this scope",
609 count
, S_name(arg_list
->id
) );
613 // enter into value table
614 S_enter( env
->value
, arg_list
->id
, arg_list
->type
);
615 env
->scope_add( arg_list
->id
);
618 f
->stack_depth
+= arg_list
->type
->size
;
621 arg_list
= arg_list
->next
;
624 // type check the code
625 if( !type_engine_check_stmt( env
, f
->code
) )
627 EM_error2( 0, "...in function '%s'.", S_name(f
->name
) );
632 env
->is_global
= TRUE
;
634 S_endScope( env
->value
);
642 //-----------------------------------------------------------------------------
643 // name: type_engine_check_func_def_import()
645 //-----------------------------------------------------------------------------
646 t_CKBOOL
type_engine_check_func_def_import( t_Env info
, a_Func_Def f
)
649 if( lookup_value( info
, f
->name
, FALSE
) )
651 EM_error2( f
->linepos
,
652 "imported identifier '%s' is already in use in namespace '%s'",
653 S_name(f
->name
), S_name(info
->name
) );
657 // look up the return type
658 f
->ret_type
= lookup_type( info
, f
->type_decl
->id
);
661 EM_error2( f
->linepos
, "imported function '%s.%s':", S_name(info
->name
), S_name(f
->name
) );
662 EM_error2( f
->linepos
, "undefined return type '%s'", S_name(f
->type_decl
->id
) );
665 f
->ret_type
->array_depth
= f
->type_decl
->array
;
667 a_Arg_List arg_list
= f
->arg_list
;
668 unsigned int count
= 1;
673 // look up in type table
674 arg_list
->type
= lookup_type( info
, arg_list
->type_decl
->id
);
675 if( !arg_list
->type
)
677 EM_error2( arg_list
->linepos
, "in imported function '%s.%s':",
678 S_name(info
->name
), S_name(f
->name
) );
679 EM_error2( arg_list
->linepos
, "argument %i '%s' has undefined type '%s'",
680 count
, S_name(arg_list
->id
), S_name(arg_list
->type_decl
->id
) );
685 f
->stack_depth
+= arg_list
->type
->size
;
688 arg_list
= arg_list
->next
;
691 // enter the name into the value table
692 S_enter( info
->value
, f
->name
, &t_function
);
693 // enter function into the function table
694 S_enter( info
->function
, f
->name
, f
);
696 f
->s_type
= ae_func_builtin
;
704 //-----------------------------------------------------------------------------
705 // name: type_engine_check_ugen_def_import()
707 //-----------------------------------------------------------------------------
708 t_CKBOOL
type_engine_check_ugen_def_import( t_Env info
, Chuck_UGen_Info
* ugen
)
710 map
<string
, bool> params
;
713 if( lookup_type( info
, insert_symbol(ugen
->name
.c_str()), FALSE
) )
715 EM_error2( ugen
->linepos
,
716 "imported ugen '%s.%s': \n type identifier '%s' is in use in namespace '%s'",
717 S_name(info
->name
), ugen
->name
.c_str(), ugen
->name
.c_str(), S_name(info
->name
) );
724 EM_error2( ugen
->linepos
,
725 "imported ugen '%s.%s': no [tick] method defined",
726 S_name(info
->name
), ugen
->name
.c_str() );
731 ugen
->add( ugen_ctrl_op
, ugen_cget_op
, "int", "op" );
732 ugen
->add( ugen_ctrl_gain
, ugen_cget_gain
, "float", "gain" );
733 ugen
->add( NULL
, ugen_cget_last
, "float", "last" );
735 // loop through ctrl parameters
736 for( unsigned int i
= 0; i
< ugen
->param_list
.size(); i
++ )
738 const Chuck_Info_Param
* param
= &ugen
->param_list
[i
];
741 t_Type t
= lookup_type( info
, insert_symbol(param
->type
.c_str()) );
744 EM_error2( ugen
->linepos
,
745 "imported ugen '%s.%s': unrecognized type '%s' for control parameter '%s'",
746 S_name(info
->name
), ugen
->name
.c_str(), param
->type
.c_str(), param
->name
.c_str() );
751 // check for duplicates - unless ugen has declared a parent,
752 // and we expect to find some duplicates.
753 // in general, this just updates the param_map and the
754 // older functions are 'forgotten' though still present
756 if( ugen
->parent
== "" && params
[param
->name
] )
758 EM_error2( ugen
->linepos
,
759 "imported ugen '%s.%s': duplicate control parameter name '%s'",
760 S_name(info
->name
), ugen
->name
.c_str(), param
->name
.c_str() );
764 // make sure there is a function
765 if( !param
->ctrl_addr
&& !param
->cget_addr
)
767 EM_error2( ugen
->linepos
,
768 "imported ugen '%s.%s': no ctrl or cget function defined for param '%s'",
769 S_name(info
->name
), ugen
->name
.c_str(), param
->name
.c_str() );
773 params
[param
->name
] = true;
776 // enter the name into the type table
777 S_enter( info
->type
, insert_symbol(ugen
->name
.c_str()),
778 make_type( ugen
->name
.c_str(), &t_ugen
, t_ugen
.size
) );
779 // enter into the ugen table
780 S_enter( info
->ugen
, insert_symbol(ugen
->name
.c_str()), (void *)ugen
);
788 //-----------------------------------------------------------------------------
789 // name: type_engine_check_value_import()
791 //-----------------------------------------------------------------------------
792 t_CKBOOL
type_engine_check_value_import( t_Env info
, S_Symbol name
,
793 S_Symbol type
, void * addr
)
796 if( lookup_value( info
, name
, FALSE
) )
799 "imported identifier '%s' is already in use in namespace '%s'",
800 name
, S_name(info
->name
) );
805 t_Type t
= lookup_type( info
, type
);
809 "imported identifier '%s.%s' has unrecognized type '%s'",
810 S_name(info
->name
), name
, type
);
815 S_enter( info
->value
, name
, t
);
817 S_enter( info
->addr
, name
, addr
);
825 //-----------------------------------------------------------------------------
826 // name: type_engine_check_stmt_list()
827 // desc: type check a stmt list
828 //-----------------------------------------------------------------------------
829 t_CKBOOL
type_engine_check_stmt_list( t_Env env
, a_Stmt_List list
)
834 // type check the stmt_list
837 if( !type_engine_check_stmt( env
, list
->stmt
) )
839 //env->out() << "type checker: statement in list does not type "
840 // << "check..." << endl;
856 //-----------------------------------------------------------------------------
857 // name: type_engine_check_stmt()
858 // desc: type check a stmt
859 //-----------------------------------------------------------------------------
860 t_CKBOOL
type_engine_check_stmt( t_Env env
, a_Stmt stmt
)
867 switch( stmt
->s_type
)
870 // env->print( "stmt_if" );
871 ret
= type_engine_check_if( env
, &stmt
->stmt_if
);
875 // env->print( "stmt_for" );
876 ret
= type_engine_check_for( env
, &stmt
->stmt_for
);
880 // env->print( "stmt_while" );
881 ret
= type_engine_check_while( env
, &stmt
->stmt_while
);
885 // env->print( "stmt_until" );
886 ret
= type_engine_check_until( env
, &stmt
->stmt_until
);
890 // evn->print( "stmt_exp" );
891 ret
= ( type_engine_check_exp( env
, stmt
->stmt_exp
) != NULL
);
895 // env->print( "switch? not implemented" );
896 ret
= type_engine_check_switch( env
, &stmt
->stmt_switch
);
900 // env->print( "return" );
901 ret
= type_engine_check_return( env
, &stmt
->stmt_return
);
905 // env->print( "case" );
906 // ret = type_engine_check_case( env, &stmt->stmt_case );
909 case ae_stmt_gotolabel
:
910 // env->print( "gotolabel" );
915 // env->print( "break? not implemented" );
919 case ae_stmt_continue
:
920 // env->print( "continue" );
925 // env->print( "code segment" );
926 S_beginScope( env
->value
);
927 ret
= type_engine_check_code_segment( env
, &stmt
->stmt_code
);
928 S_endScope( env
->value
);
932 // // env->print( "func_def" );
933 // ret = type_engine_check_func_def( env, stmt->stmt_func );
937 EM_error2( stmt
->linepos
,
938 "internal compiler error - no stmt type '%i'!", stmt
->s_type
);
948 //-----------------------------------------------------------------------------
949 // name: type_engine_check_exp()
950 // desc: type check an exp
951 //-----------------------------------------------------------------------------
952 t_Type
type_engine_check_exp( t_Env env
, a_Exp exp
)
960 switch( curr
->s_type
)
963 curr
->type
= type_engine_check_exp_binary( env
, &curr
->binary
);
967 curr
->type
= type_engine_check_exp_unary( env
, &curr
->unary
);
971 curr
->type
= type_engine_check_exp_cast( env
, &curr
->cast
);
975 curr
->type
= type_engine_check_exp_postfix( env
, &curr
->postfix
);
979 curr
->type
= type_engine_check_exp_dur( env
, &curr
->dur
);
983 curr
->type
= type_engine_check_primary( env
, &curr
->primary
);
987 curr
->type
= type_engine_check_exp_array( env
, &curr
->array
);
990 case ae_exp_func_call
:
991 curr
->type
= type_engine_check_exp_func_call( env
, &curr
->func_call
);
992 curr
->func_call
.ret_type
= curr
->type
;
995 case ae_exp_dot_member
:
996 curr
->type
= type_engine_check_exp_dot_member( env
, &curr
->dot_member
);
1000 curr
->type
= type_engine_check_exp_if( env
, &curr
->exp_if
);
1004 curr
->type
= type_engine_check_exp_decl( env
, &curr
->decl
);
1007 case ae_exp_namespace
:
1008 curr
->type
= type_engine_check_exp_namespace( env
, &curr
->name_space
);
1012 curr->exp_type = (t_Type)S_look( env->type, curr->a_new->type );
1017 EM_error2( curr
->linepos
, "internal compiler error - no expression '%i'",
1032 //-----------------------------------------------------------------------------
1033 // name: type_engine_check_primary()
1034 // desc: check primary
1035 //-----------------------------------------------------------------------------
1036 t_Type
type_engine_check_primary( t_Env env
, a_Exp_Primary exp
)
1040 switch( exp
->s_type
)
1042 case ae_primary_var
:
1044 type
= lookup_value( env
, exp
->var
);
1046 EM_error2( exp
->linepos
, "undefined variable '%s'",
1048 else if( type
->type
== __te_system_namespace__
||
1049 type
->type
== __te_system_class__
)
1051 env
->nspc_name
= exp
->var
;
1052 env
->is_nspc
= type
->type
== __te_system_namespace__
;
1053 env
->child
= ( type
->type
== __te_system_namespace__
?
1054 lookup_namespace( env
, exp
->var
) : NULL
);
1056 else if( isa( type
, &t_ugen
) )
1058 env
->nspc_name
= exp
->var
;
1063 case ae_primary_num
:
1067 case ae_primary_uint
:
1071 case ae_primary_float
:
1075 case ae_primary_str
:
1079 case ae_primary_exp
:
1080 type
= type_engine_check_exp( env
, exp
->exp
);
1084 EM_error2( exp
->linepos
,
1085 "internal compiler error - no primary expression '%i'", exp
->s_type
);
1095 //-----------------------------------------------------------------------------
1096 // name: type_engine_check_op_chuck()
1097 // desc: type check chuck operator
1098 //-----------------------------------------------------------------------------
1099 t_Type
type_engine_check_op_chuck( t_Env env
, t_Type left
, t_Type right
)
1101 if( (left
->type
== te_string
) && (left
->type
== right
->type
) )
1103 if( (left
->type
== te_dur
) && (right
->type
== left
->type
) )
1105 if( (left
->type
== te_dur
) && (right
->type
== te_time
) )
1107 if( left
->type
== __te_system_out__
)
1109 if( right
->type
== __te_system_out__
)
1111 if( left
->type
== te_int
&& right
->type
== te_midiout
)
1113 if( left
->type
== te_midiout
&& right
->type
== te_int
)
1115 if( left
->type
== te_midiin
&& right
->type
== te_int
)
1117 if( left
->type
!= te_null
&& left
->type
== right
->type
)
1121 if( left
->type
== te_string
&& right
->type
== __te_system_namespace__
)
1125 if( left
->type
== te_int
&& right
->type
== te_uint
)
1127 if( left
->type
== te_uint
&& right
->type
== te_int
)
1129 if( left
->parent
&& right
->parent
&&
1130 left
->parent
->type
== te_ugen
&& right
->parent
->type
== te_ugen
)
1139 //-----------------------------------------------------------------------------
1140 // name: type_engine_check_op_unchuck()
1142 //-----------------------------------------------------------------------------
1143 t_Type
type_engine_check_op_unchuck( t_Env env
, t_Type left
, t_Type right
)
1145 if( left
->parent
&& right
->parent
&&
1146 left
->parent
->type
== te_ugen
&& right
->parent
->type
== te_ugen
)
1155 //-----------------------------------------------------------------------------
1156 // name: type_engine_check_op()
1157 // desc: type check op
1158 //-----------------------------------------------------------------------------
1159 t_Type
type_engine_check_op( t_Env env
, ae_Operator op
,
1160 t_Type left
, t_Type right
)
1165 return type_engine_check_op_chuck( env
, left
, right
);
1168 return type_engine_check_op_unchuck( env
, left
, right
);
1171 if( ( (left
->type
== te_dur
) && (right
->type
== te_time
) ) ||
1172 ( (left
->type
== te_time
) && (right
->type
== te_dur
) ) )
1175 if( (left
->type
== te_time
) && (right
->type
== te_dur
) )
1177 if( (left
->type
== te_dur
) && (right
->type
== left
->type
) )
1179 if( (left
->type
== te_time
) && (right
->type
== left
->type
) ) // XXX time - time = dur
1183 if( (left
->type
== te_dur
) && (right
->type
== left
->type
) )
1185 case ae_op_plus_chuck
:
1186 case ae_op_minus_chuck
:
1187 case ae_op_times_chuck
:
1188 case ae_op_divide_chuck
:
1189 if( (left
->type
== te_float
) && (left
->type
== right
->type
) )
1191 if( (left
->type
== te_double
) && (left
->type
== right
->type
) )
1193 if( (left
->type
== te_dur
) && (right
->type
== te_float
) )
1202 if( (left
->type
== te_int
) && (left
->type
== right
->type
) )
1204 if( (left
->type
== te_uint
) && (left
->type
== right
->type
) )
1206 if( (left
->type
== te_float
) && (left
->type
== right
->type
) )
1208 if( (left
->type
== te_double
) && (left
->type
== right
->type
) )
1210 if( (left
->type
== te_dur
) && (left
->type
== right
->type
) )
1212 if( (left
->type
== te_time
) && (left
->type
== right
->type
) )
1214 if( (left
->type
== te_int
) && (right
->type
== te_uint
) )
1216 if( (left
->type
== te_uint
) && (right
->type
== te_int
) )
1224 if( op
== ae_op_s_xor
&& ( (left
->type
== te_midiin
) || (left
->type
== te_midiout
) ) &&
1225 ( right
->type
== te_int
) )
1227 case ae_op_shift_left
:
1228 case ae_op_shift_right
:
1230 case ae_op_s_and_chuck
:
1231 case ae_op_s_or_chuck
:
1232 case ae_op_s_xor_chuck
:
1233 case ae_op_shift_right_chuck
:
1234 case ae_op_shift_left_chuck
:
1235 case ae_op_percent_chuck
:
1238 case ae_op_at_chuck
:
1239 if( (left
->type
== te_int
) && (left
->type
== right
->type
) )
1241 if( (left
->type
== te_uint
) && (left
->type
== right
->type
) )
1243 if( (left
->type
== te_time
) && (right
->type
== te_dur
) )
1245 if( (left
->type
== te_dur
) && (right
->type
== te_dur
) )
1256 //-----------------------------------------------------------------------------
1259 //-----------------------------------------------------------------------------
1260 t_Type
type_engine_check_exp_binary( t_Env env
, a_Exp_Binary binary
)
1262 a_Exp cl
= binary
->lhs
, cr
= binary
->rhs
;
1266 if( binary
->op
== ae_op_chuck
&& cr
->s_type
== ae_exp_dot_member
)
1267 cr
->dot_member
.flag
= 1;
1269 t_Type left
= type_engine_check_exp( env
, cl
);
1270 t_Type right
= type_engine_check_exp( env
, cr
);
1272 if( !left
|| !right
)
1281 ret
= type_engine_check_op( env
, binary
->op
, cl
->type
, cr
->type
);
1284 EM_error2( binary
->linepos
,
1285 "no suitable resolution for binary operator '%s' on types '%s' and '%s'",
1286 op2str(binary
->op
), cl
->type
->name
, cr
->type
->name
);
1292 if( binary
->op
== ae_op_chuck
&& cl
->type
->type
== te_string
&&
1293 cr
->type
->type
== __te_system_namespace__
&& cl
->s_type
== ae_exp_primary
&&
1294 cl
->primary
.s_type
== ae_primary_str
)
1297 while( e
->parent
) e
= e
->parent
;
1298 Chuck_DLL
* dll
= e
->vm
->dll_load( cl
->primary
.str
, cl
->primary
.str
);
1299 if( !dll
&& cl
->primary
.str
[0] != '.' && cl
->primary
.str
[0] != '/' )
1300 dll
= e
->vm
->dll_load( (string("./") + cl
->primary
.str
).c_str(),
1304 EM_error2( binary
->linepos
,
1305 "ChucK DLL load failed...\n [reason]: %s", e
->vm
->last_error() );
1309 ((Chuck_DL_Query
*)dll
->query())->linepos
= binary
->linepos
;
1310 type_engine_add_dll( e
, dll
, S_name(cr
->name_space
.name
) );
1325 //-----------------------------------------------------------------------------
1326 // name: type_engine_check_exp_unary
1328 //-----------------------------------------------------------------------------
1329 t_Type
type_engine_check_exp_unary( t_Env env
, a_Exp_Unary unary
)
1331 t_Type t
= type_engine_check_exp( env
, unary
->exp
);
1335 case ae_op_plusplus
:
1336 case ae_op_minusminus
:
1337 if( !type_engine_check_exp_mem( env
, unary
->exp
) )
1339 EM_error2( unary
->linepos
, "non-lvalue for (prefix) operator ++ or --" );
1343 if( t
->type
== te_int
|| t
->type
== te_uint
|| t
->type
== te_float
)
1347 EM_error2( unary
->linepos
, "bad type '%s' for unary operator '%s'",
1348 t
->name
, op2str(unary
->op
) );
1352 case ae_op_exclamation
:
1354 if( t
->type
== te_int
|| t
->type
== te_uint
)
1356 if( unary
->op
== ae_op_minus
&& t
->type
== te_float
)
1360 EM_error2( unary
->linepos
, "bad type '%s' for unary operator '%s'",
1361 t
->name
, op2str(unary
->op
) );
1365 if( unary
->exp
->s_type
== ae_exp_func_call
)
1369 EM_error2( unary
->linepos
, "only function calls can be sporked" );
1373 EM_error2( unary
->linepos
, "unrecognized unary operator '%s'",
1374 op2str(unary
->op
) );
1384 //-----------------------------------------------------------------------------
1385 // name: type_engine_check_cast_valid()
1387 //-----------------------------------------------------------------------------
1388 t_CKBOOL
type_engine_check_cast_valid( t_Env env
, t_Type to
, t_Type from
)
1390 if( to
->type
== from
->type
) return TRUE
;
1391 if( to
->type
== te_int
&& from
->type
== te_float
) return TRUE
;
1392 if( to
->type
== te_float
&& from
->type
== te_int
) return TRUE
;
1400 //-----------------------------------------------------------------------------
1401 // name: type_engine_check_exp_cast()
1403 //-----------------------------------------------------------------------------
1404 t_Type
type_engine_check_exp_cast( t_Env env
, a_Exp_Cast cast
)
1406 t_Type t
= type_engine_check_exp( env
, cast
->exp
);
1407 if( !t
) return NULL
;
1409 t_Type t2
= lookup_type( env
, cast
->type
, TRUE
);
1412 EM_error2( cast
->linepos
,
1413 "casting to unknown type '%s'...", S_name(cast
->type
) );
1417 if( !type_engine_check_cast_valid( env
, t2
, t
) )
1419 EM_error2( cast
->linepos
,
1420 "cannot cast to type '%s' from '%s'...",
1421 t2
->name
, t
->name
);
1431 //-----------------------------------------------------------------------------
1432 // name: type_engine_check_exp_postfix
1434 //-----------------------------------------------------------------------------
1435 t_Type
type_engine_check_exp_postfix( t_Env env
, a_Exp_Postfix postfix
)
1437 t_Type t
= type_engine_check_exp( env
, postfix
->exp
);
1442 switch( postfix
->op
)
1444 case ae_op_plusplus
:
1445 case ae_op_minusminus
:
1446 if( !type_engine_check_exp_mem( env
, postfix
->exp
) )
1448 EM_error2( postfix
->linepos
, "++/-- used on non-assignable value" );
1452 if( t
->type
== te_int
|| t
->type
== te_uint
|| t
->type
== te_float
)
1456 EM_error2( postfix
->linepos
, "bad type '%s' for unary operator '%s'",
1457 t
->name
, op2str(postfix
->op
) );
1461 EM_error2( postfix
->linepos
,
1462 "internal compiler error - unrecognized postfix operator '%s'", op2str(postfix
->op
) );
1473 //-----------------------------------------------------------------------------
1474 // name: type_engine_check_exp_dur
1476 //-----------------------------------------------------------------------------
1477 t_Type
type_engine_check_exp_dur( t_Env env
, a_Exp_Dur dur
)
1479 t_Type base
= type_engine_check_exp( env
, dur
->base
);
1480 t_Type unit
= type_engine_check_exp( env
, dur
->unit
);
1483 if( !base
|| !unit
)
1487 if( base
->type
!= te_float
&& base
->type
!= te_int
)
1489 EM_error2( dur
->base
->linepos
,
1490 "base type '%s' illegal in dur expression",
1496 if( unit
->type
!= te_dur
)
1498 EM_error2( dur
->unit
->linepos
,
1499 "unit in dur expression has type '%s' - it must have type 'dur'",
1510 //-----------------------------------------------------------------------------
1511 // name: type_engine_check_exp_array
1513 //-----------------------------------------------------------------------------
1514 t_Type
type_engine_check_exp_array( t_Env env
, a_Exp_Array array
)
1522 //-----------------------------------------------------------------------------
1523 // name: type_engine_check_exp_func_call
1525 //-----------------------------------------------------------------------------
1526 t_Type
type_engine_check_exp_func_call( t_Env env
, a_Exp_Func_Call func_call
)
1528 a_Func_Def func
= NULL
;
1530 t_Type f
= type_engine_check_exp( env
, func_call
->func
);
1531 if( !f
) return NULL
;
1534 if( f
->type
!= te_function
)
1536 EM_error2( func_call
->linepos
, "function call using a non-function value" );
1541 if( func_call
->func
->s_type
== ae_exp_primary
)
1543 if( func_call
->func
->primary
.s_type
== ae_primary_var
)
1546 func
= lookup_func( env
, func_call
->func
->primary
.var
);
1549 EM_error2( func_call
->linepos
,
1550 "no function named '%s' defined", S_name(func_call
->func
->primary
.var
) );
1556 EM_error2( func_call
->linepos
, "function call using illegal f-value" );
1560 name
= S_name( func_call
->func
->primary
.var
);
1562 else // namespace or class
1564 t_Env e
= env
->child
;
1565 S_Symbol s
= env
->nspc_name
;
1567 // make sure both there
1570 EM_error2( func_call
->linepos
, "type checker: missing env/symbol in func call" );
1575 func
= lookup_func( e
, s
);
1578 EM_error2( func_call
->linepos
,
1579 "no function named '%s' defined in namespace/class '%s'",
1580 S_name(s
), S_name(e
->name
) );
1584 name
= S_name( func
->name
);
1587 if( func_call
->args
)
1589 a
= type_engine_check_exp( env
, func_call
->args
);
1590 if( !a
) return NULL
;
1593 a_Exp e
= func_call
->args
;
1594 a_Arg_List e1
= func
->arg_list
;
1595 unsigned int count
= 1;
1602 EM_error2( func_call
->linepos
,
1603 "extra argument(s) in function call '%s' %i %s",
1604 name
, e
->s_type
, e
->type
->name
);
1608 if( e
->type
->type
!= e1
->type
->type
)
1610 EM_error2( func_call
->linepos
,
1611 "argument '%i' of function call '%s' has type '%s' -- expecting type '%s'",
1612 count
, name
, e
->type
->name
, e1
->type
->name
);
1623 EM_error2( func_call
->linepos
,
1624 "missing argument(s) in function call '%s', next arg: '%s %s'",
1625 S_name(func_call
->func
->primary
.var
), e1
->type
->name
, S_name(e1
->id
) );
1629 return func
->ret_type
;
1635 //-----------------------------------------------------------------------------
1636 // name: type_engine_check_exp_dot_member
1638 //-----------------------------------------------------------------------------
1639 t_Type
type_engine_check_exp_dot_member( t_Env env
, a_Exp_Dot_Member member
)
1641 t_Type t_base
= type_engine_check_exp( env
, member
->base
);
1646 if( t_base
->type
== __te_system_namespace__
)
1648 // look for the namespace (name should be already resolved)
1649 t_Env info
= lookup_namespace( env
, env
->nspc_name
, FALSE
);
1652 EM_error2( member
->linepos
,
1653 "cannot find namespace '%s'",
1654 S_name(env
->nspc_name
) );
1659 t_Type t_member
= lookup_value( info
, member
->id
, FALSE
);
1662 EM_error2( member
->linepos
,
1663 "cannot find member '%s' in namespace '%s'",
1664 S_name(member
->id
), S_name(info
->name
) );
1670 env
->nspc_name
= member
->id
;
1674 else if( isa( t_base
, &t_ugen
) )
1677 Chuck_UGen_Info
* info
= lookup_ugen( env
, insert_symbol(t_base
->name
), FALSE
);
1680 EM_error2( member
->linepos
,
1681 "cannot find unit generator '%s'",
1687 Chuck_Info_Param param
= info
->param_map
[S_name(member
->id
)];
1688 if( param
.type
== "" )
1690 EM_error2( member
->linepos
,
1691 "cannot find control parameter '%s.%s'",
1692 t_base
->name
, S_name(member
->id
) );
1696 env
->nspc_name
= NULL
;
1698 // look for the type
1699 t_Type t_param
= lookup_type( env
, insert_symbol(param
.type
.c_str()) );
1702 EM_error2( member
->linepos
,
1703 "type checker: internal error: cannot find param type '%s'",
1704 param
.type
.c_str() );
1708 t_Type t
= dup_type( t_param
);
1709 // copy the function pointer
1710 member
->data
= (uint
)param
.ctrl_addr
;
1711 member
->data2
= (uint
)param
.cget_addr
;
1712 if( !member
->data
&& !member
->data2
)
1714 EM_error2( member
->linepos
,
1715 "type checker: internal error: cannot find ugen ctrl or cget for '%s'",
1716 param
.name
.c_str() );
1720 if( member
->flag
&& !member
->data
)
1722 EM_error2( member
->linepos
,
1723 "type checker: cannot chuck values to '%s.%s' - it is read-only",
1724 t_base
->name
, S_name(member
->id
) );
1727 else if( !member
->flag
&& !member
->data2
)
1729 EM_error2( member
->linepos
,
1730 "type checker: cannot use value from '%s.%s' - it is write-only",
1731 t_base
->name
, S_name(member
->id
) );
1739 EM_error2( member
->linepos
,
1740 "internal error: class namespace not impl" );
1750 //-----------------------------------------------------------------------------
1751 // name: type_engine_check_exp_if
1753 //-----------------------------------------------------------------------------
1754 t_Type
type_engine_check_exp_if( t_Env env
, a_Exp_If exp_if
)
1756 t_Type cond
= type_engine_check_exp( env
, exp_if
->cond
);
1757 t_Type if_exp
= type_engine_check_exp( env
, exp_if
->if_exp
);
1758 t_Type else_exp
= type_engine_check_exp( env
, exp_if
->else_exp
);
1766 //-----------------------------------------------------------------------------
1767 // name: type_engine_check_exp_decl()
1769 //-----------------------------------------------------------------------------
1770 t_Type
type_engine_check_exp_decl( t_Env env
, a_Exp_Decl decl
)
1772 a_Var_Decl var_decl
= decl
->var_decl_list
->var_decl
;
1774 t_Type t
= NULL
, t2
= NULL
;
1776 if( var_decl
->isarray
)
1778 EM_error2( decl
->linepos
, "array not impl!" );
1784 // look up the type in the type binding
1785 t
= lookup_type( env
, decl
->type
);
1791 EM_error2( decl
->linepos
, "undefined type '%s'",
1792 S_name(decl
->type
) );
1796 // check to see if value is there
1797 t2
= lookup_value( env
, var_decl
->id
, FALSE
);
1798 if( env
->scope_lookup( var_decl
->id
) )
1800 // error - already defined in local scope
1801 EM_error2( decl
->linepos
,
1802 "'%s' has already been defined in the same scope",
1803 S_name(var_decl
->id
) );
1807 // enter the type into the var->type value binding
1808 S_enter( env
->value
, var_decl
->id
, t
);
1809 env
->scope_add( var_decl
->id
);
1818 //-----------------------------------------------------------------------------
1819 // name: type_engine_check_exp_namespace( )
1821 //-----------------------------------------------------------------------------
1822 t_Type
type_engine_check_exp_namespace( t_Env env
, a_Exp_Namespace name_space
)
1824 return &t_system_namespace
;
1830 //-----------------------------------------------------------------------------
1831 // name: type_engine_check_if()
1832 // desc: type check a stmt
1833 //-----------------------------------------------------------------------------
1834 t_CKBOOL
type_engine_check_if( t_Env env
, a_Stmt_If stmt
)
1836 // check the conditional
1837 if( !type_engine_check_exp( env
, stmt
->cond
) )
1839 // env->out() << "type checker: bad type in if condition" << endl;
1843 // check if then else, if there is one
1844 if( !type_engine_check_stmt( env
, stmt
->if_body
) )
1846 // env->out() << "type checker: bad type in if statement" << endl;
1850 if( stmt
->else_body
)
1852 if( !type_engine_check_stmt( env
, stmt
->else_body
) )
1854 // env->out() << "type checker: bad type in else statement" << endl;
1865 //-----------------------------------------------------------------------------
1866 // name: type_engine_check_for()
1867 // desc: type check a stmt
1868 //-----------------------------------------------------------------------------
1869 t_CKBOOL
type_engine_check_for( t_Env env
, a_Stmt_For stmt
)
1871 // check the conditional
1872 if( !type_engine_check_stmt( env
, stmt
->c1
) )
1874 // env->out() << "type checker: bad type in for exp 1" << endl;
1878 // check the conditional
1879 if( !type_engine_check_stmt( env
, stmt
->c2
) )
1881 // env->out() << "type checker: bad type in for exp 2" << endl;
1885 // check the conditional
1886 if( stmt
->c3
&& !type_engine_check_exp( env
, stmt
->c3
) )
1888 // env->out() << "type checker: bad type in for exp 3" << endl;
1892 if( !type_engine_check_stmt( env
, stmt
->body
) )
1894 // env->out() << "type checker: bad type in for body" << endl;
1904 //-----------------------------------------------------------------------------
1905 // name: type_engine_check_code_segment()
1906 // desc: type check a stmt
1907 //-----------------------------------------------------------------------------
1908 t_CKBOOL
type_engine_check_code_segment( t_Env env
, a_Stmt_Code stmt
)
1910 return type_engine_check_stmt_list( env
, stmt
->stmt_list
);
1916 //-----------------------------------------------------------------------------
1917 // name: type_engine_check_while()
1918 // desc: type check a stmt
1919 //-----------------------------------------------------------------------------
1920 t_CKBOOL
type_engine_check_while( t_Env env
, a_Stmt_While stmt
)
1922 if( !type_engine_check_exp( env
, stmt
->cond
) )
1924 // env->out() << "type checker: while condition does not type check" << endl;
1928 if( !type_engine_check_stmt( env
, stmt
->body
) )
1930 // env->out() << "type checker: while statement does not type check" << endl;
1940 //-----------------------------------------------------------------------------
1941 // name: type_engine_check_until()
1942 // desc: type check a stmt
1943 //-----------------------------------------------------------------------------
1944 t_CKBOOL
type_engine_check_until( t_Env env
, a_Stmt_Until stmt
)
1946 if( !type_engine_check_exp( env
, stmt
->cond
) )
1948 // env->out() << "type checker: while condition does not type check" << endl;
1952 if( !type_engine_check_stmt( env
, stmt
->body
) )
1954 // env->out() << "type checker: while statement does not type check" << endl;
1964 //-----------------------------------------------------------------------------
1965 // name: type_engine_check_return()
1966 // desc: type check a stmt
1967 //-----------------------------------------------------------------------------
1968 t_CKBOOL
type_engine_check_return( t_Env env
, a_Stmt_Return stmt
)
1970 t_Type ret_type
= NULL
;
1972 if( !env
->func_def
)
1974 EM_error2( stmt
->linepos
, "'return' statement found outside function definition" );
1979 ret_type
= type_engine_check_exp( env
, stmt
->val
);
1983 if( ret_type
&& ret_type
!= env
->func_def
->ret_type
)
1985 EM_error2( stmt
->linepos
,
1986 "function '%s' was defined with return type '%s' -- but returning type '%s'",
1987 S_name(env
->func_def
->name
), env
->func_def
->ret_type
->name
, ret_type
->name
);
1991 return ret_type
!= NULL
;
1997 //-----------------------------------------------------------------------------
1998 // name: type_engine_check_switch()
1999 // desc: type check a stmt
2000 //-----------------------------------------------------------------------------
2001 t_CKBOOL
type_engine_check_switch( t_Env env
, a_Stmt_Switch stmt
)
2009 //-----------------------------------------------------------------------------
2010 // name: lookup_type()
2012 //-----------------------------------------------------------------------------
2013 t_Type
lookup_type( t_Env env
, S_Symbol type_name
, t_CKBOOL climb
)
2015 t_Type t
= (t_Type
)S_look( env
->type
, type_name
);
2016 if( climb
&& !t
&& env
->parent
)
2017 return lookup_type( env
->parent
, type_name
, climb
);
2024 //-----------------------------------------------------------------------------
2025 // name: lookup_value()
2027 //-----------------------------------------------------------------------------
2028 t_Type
lookup_value( t_Env env
, S_Symbol value_name
, t_CKBOOL climb
)
2030 t_Type t
= (t_Type
)S_look( env
->value
, value_name
);
2031 if( climb
&& !t
&& env
->parent
)
2032 return lookup_value( env
->parent
, value_name
, climb
);
2039 //-----------------------------------------------------------------------------
2040 // name: lookup_func()
2042 //-----------------------------------------------------------------------------
2043 a_Func_Def
lookup_func( t_Env env
, S_Symbol func_name
, t_CKBOOL climb
)
2045 a_Func_Def f
= (a_Func_Def
)S_look( env
->function
, func_name
);
2046 if( climb
&& !f
&& env
->parent
)
2047 return lookup_func( env
->parent
, func_name
, climb
);
2054 //-----------------------------------------------------------------------------
2055 // name: lookup_ugen()
2057 //-----------------------------------------------------------------------------
2058 Chuck_UGen_Info
* lookup_ugen( t_Env env
, S_Symbol ugen_name
, t_CKBOOL climb
)
2060 Chuck_UGen_Info
* ugen
= (Chuck_UGen_Info
*)S_look( env
->ugen
, ugen_name
);
2061 if( climb
&& !ugen
&& env
->parent
)
2062 return lookup_ugen( env
->parent
, ugen_name
, climb
);
2069 //-----------------------------------------------------------------------------
2070 // name: lookup_namespace()
2072 //-----------------------------------------------------------------------------
2073 t_Env
lookup_namespace( t_Env env
, S_Symbol nspc
, t_CKBOOL climb
)
2075 t_Env e
= (t_Env
)S_look( env
->name_space
, nspc
);
2076 if( climb
&& !e
&& env
->parent
)
2077 return lookup_namespace( env
->parent
, nspc
, climb
);
2084 //-----------------------------------------------------------------------------
2085 // name: lookup_addr()
2087 //-----------------------------------------------------------------------------
2088 void * lookup_addr( t_Env env
, S_Symbol value
, t_CKBOOL climb
)
2090 void * v
= S_look( env
->addr
, value
);
2091 if( climb
&& !v
&& env
->parent
)
2092 return lookup_addr( env
->parent
, value
, climb
);
2099 //-----------------------------------------------------------------------------
2100 // name: type_engine_check_exp_mem()
2101 // desc: type check an exp memory
2102 //-----------------------------------------------------------------------------
2103 t_CKBOOL
type_engine_check_exp_mem( t_Env env
, a_Exp exp
)
2106 t_CKBOOL val
= TRUE
;
2108 while( curr
&& val
)
2111 switch( curr
->s_type
)
2113 case ae_exp_primary
:
2114 val
= type_engine_check_primary_mem( env
, &curr
->primary
);
2118 val
= type_engine_check_exp_array_mem( env
, &curr
->array
);
2121 case ae_exp_func_call
:
2122 val
= type_engine_check_exp_func_call_mem( env
, &curr
->func_call
);
2125 case ae_exp_dot_member
:
2126 val
= type_engine_check_exp_dot_member_mem( env
, &curr
->dot_member
);
2140 //-----------------------------------------------------------------------------
2141 // name: type_engine_check_exp_mem()
2142 // desc: type check an primary exp memory
2143 //-----------------------------------------------------------------------------
2144 t_CKBOOL
type_engine_check_primary_mem( t_Env env
, a_Exp_Primary exp
)
2146 t_CKBOOL val
= FALSE
;
2148 switch( exp
->s_type
)
2150 case ae_primary_var
:
2151 val
= ( lookup_value( env
, exp
->var
) != NULL
);
2154 case ae_primary_exp
:
2155 val
= type_engine_check_exp_mem( env
, exp
->exp
);
2159 // env->out() << "type checker: bad primary [mem] values..." << endl;
2169 //-----------------------------------------------------------------------------
2170 // name: type_engine_check_exp_dot_member_mem()
2171 // desc: type check an dot exp memory
2172 //-----------------------------------------------------------------------------
2173 t_CKBOOL
type_engine_check_exp_dot_member_mem( t_Env env
, a_Exp_Dot_Member member
)
2181 //-----------------------------------------------------------------------------
2182 // name: type_engine_check_exp_array_mem()
2183 // desc: type check an array exp memory
2184 //-----------------------------------------------------------------------------
2185 t_CKBOOL
type_engine_check_exp_array_mem( t_Env env
, a_Exp_Array array
)
2193 //-----------------------------------------------------------------------------
2194 // name: type_engine_check_exp_func_call_mem()
2195 // desc: type check an func call exp memory
2196 //-----------------------------------------------------------------------------
2197 t_CKBOOL
type_engine_check_exp_func_call_mem( t_Env env
, a_Exp_Func_Call func_call
)