*** empty log message ***
[chuck-blob.git] / exile / v1 / src / chuck_type.cpp
blobbff531f40f4032d71a256594194b685a302ba425
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
22 U.S.A.
23 -----------------------------------------------------------------------------*/
25 //-----------------------------------------------------------------------------
26 // file: chuck_types.cpp
27 // desc: ...
29 // author: Ge Wang (gewang@cs.princeton.edu)
30 // Perry R. Cook (prc@cs.princeton.edu)
31 // date: Autumn 2002
32 //-----------------------------------------------------------------------------
33 #include <stdlib.h>
34 #include <string>
35 #include <vector>
36 #include <map>
37 using namespace std;
39 #include "chuck_type.h"
40 #include "chuck_instr.h"
41 #include "chuck_vm.h"
42 #include "chuck_dl.h"
43 #include "chuck_errmsg.h"
44 #include "chuck_symbol.h"
49 //-----------------------------------------------------------------------------
50 // name: struct t_Env_
51 // desc: type check env
52 //-----------------------------------------------------------------------------
53 struct t_Env_
55 // lookup tables
56 S_table value;
57 S_table type;
58 S_table function;
59 S_table ugen;
60 S_table name_space;
61 S_table class_defs;
62 S_table addr;
64 // scope maps
65 vector<map<S_Symbol, S_Symbol> *> scope;
67 // data
68 S_Symbol name;
69 t_Env parent;
70 t_CKBOOL is_class;
71 map<Chuck_DLL *, bool> dlls;
72 Chuck_VM * vm;
74 // state
75 t_CKBOOL is_global;
76 a_Func_Def func_def;
77 S_Symbol nspc_name;
78 t_CKBOOL is_nspc;
79 t_Env child;
81 t_Env_() { this->scope_push(); }
82 ~t_Env_() { this->scope_pop(); }
83 // functions
84 void scope_push()
85 { scope.push_back( new map<S_Symbol, S_Symbol> ); }
86 void scope_pop()
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_
99 // desc: class def
100 //-----------------------------------------------------------------------------
101 struct t_Class_Info_
103 t_Type type;
104 string name;
105 vector<t_Type> fields;
106 vector<a_Func_Def> funcs;
108 // constructor
109 t_Class_Info_() { type = NULL; }
115 // types
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 *) };
159 // forward reference
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 );
199 // make a new type
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 );
206 t->parent = parent;
207 t->size = size;
208 t->dyn = TRUE;
210 return t;
213 // dup type
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;
218 return t;
221 // isa
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;
227 else
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_;
243 // allocate tables
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 );
251 e->parent = parent;
252 e->vm = ( parent ? parent->vm : NULL );
253 e->is_class = FALSE; // this is a namespace
255 // init the state
256 e->is_global = TRUE;
257 e->func_def = NULL;
258 e->nspc_name = NULL;
259 e->is_nspc = TRUE;
260 e->child = NULL;
262 return e;
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 );
276 e->vm = vm;
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 );
305 // null
306 S_enter( e->value, insert_symbol( "null" ), &t_null );
307 // time
308 S_enter( e->value, insert_symbol( "now" ), &t_time );
309 S_enter( e->value, insert_symbol( "start" ), &t_time );
310 // dur
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 );
340 // global namespace
341 S_enter( e->value, insert_symbol( "global" ), &t_system_namespace );
342 S_enter( e->name_space, insert_symbol( "global" ), e );
344 return e;
350 //-----------------------------------------------------------------------------
351 // name: do_make_args()
352 // desc: ...
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() )
358 return NULL;
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 );
363 else
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 );
368 return args;
372 // ctrl op
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 ) { }
376 // ctrl gain
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 ) { }
380 // cget last
381 UGEN_CGET ugen_cget_last( t_CKTIME now, void * data, void * out ) { }
384 //-----------------------------------------------------------------------------
385 // name: type_engine_add_dll()
386 // desc: ...
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 ) );
393 // if not there
394 if( info && info->dlls[dll] )
395 return FALSE;
397 if( !info )
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++ )
409 // the prototype
410 Chuck_DL_Proto * proto = &query->dll_exports[i];
412 // add func
413 if( proto->is_func )
415 // type decl
416 a_Type_Decl rtype = new_type_decl( (char *)proto->type.c_str(), 0 );
417 // arg list
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 );
424 // set the pointer
425 func->builtin = (builtin_func_ptr)proto->addr;
426 func->linepos = query->linepos;
427 // type check it
428 if( !type_engine_check_func_def_import( info, func ) )
430 // clean up
431 info->dlls.erase( dll );
432 return FALSE;
435 else
437 // add value
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 );
444 return FALSE;
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 ) )
456 // clean up
457 // info->dlls.erase( dll );
458 return FALSE;
462 // flag
463 info->dlls[dll] = true;
465 return TRUE;
472 //-----------------------------------------------------------------------------
473 // name: type_engine_shutdown()
474 // desc: shutdown a type engine
475 //-----------------------------------------------------------------------------
476 t_CKBOOL type_engine_shutdown( t_Env env )
478 // deallocate
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 );
485 delete env;
487 return TRUE;
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 )
499 t_CKBOOL ret = TRUE;
501 if( !prog )
502 return FALSE;
504 while( prog && ret )
506 switch( prog->section->s_type )
508 case ae_section_stmt:
509 ret = type_engine_check_stmt_list( env, prog->section->stmt_list );
510 break;
512 case ae_section_func:
513 ret = type_engine_check_func_def( env, prog->section->func_def );
514 break;
516 case ae_section_class:
517 EM_error2( prog->linepos, "class def not impl!" );
518 ret = FALSE;
519 break;
522 prog = prog->next;
525 return ret;
531 //-----------------------------------------------------------------------------
532 // name: type_engine_begin() type_engine_end()
533 // desc: ...
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()
545 // desc: ...
546 //-----------------------------------------------------------------------------
547 t_CKBOOL type_engine_check_func_def( t_Env env, a_Func_Def f )
549 // look up the value
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) );
554 return FALSE;
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 );
562 // user
563 f->s_type = ae_func_user;
565 // push the scope
566 S_beginScope( env->value );
567 env->scope_push( );
568 // set global
569 env->is_global = FALSE;
570 // set the func def
571 env->func_def = f;
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 );
579 // no return type
580 if( !f->ret_type )
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) );
584 return FALSE;
586 // f->ret_type->array_depth = f->type_decl->array;
588 a_Arg_List arg_list = f->arg_list;
589 unsigned int count = 1;
590 f->stack_depth = 0;
592 while( arg_list )
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) );
601 return FALSE;
604 // look up in scope
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) );
610 return FALSE;
613 // enter into value table
614 S_enter( env->value, arg_list->id, arg_list->type );
615 env->scope_add( arg_list->id );
617 // stack
618 f->stack_depth += arg_list->type->size;
620 // next arg
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) );
628 return FALSE;
631 // set global
632 env->is_global = TRUE;
633 // pop the scope
634 S_endScope( env->value );
636 return TRUE;
642 //-----------------------------------------------------------------------------
643 // name: type_engine_check_func_def_import()
644 // desc: ...
645 //-----------------------------------------------------------------------------
646 t_CKBOOL type_engine_check_func_def_import( t_Env info, a_Func_Def f )
648 // look up the value
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) );
654 return FALSE;
657 // look up the return type
658 f->ret_type = lookup_type( info, f->type_decl->id );
659 if( !f->ret_type )
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) );
663 return FALSE;
665 f->ret_type->array_depth = f->type_decl->array;
667 a_Arg_List arg_list = f->arg_list;
668 unsigned int count = 1;
669 f->stack_depth = 0;
671 while( arg_list )
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) );
681 return FALSE;
684 // stack depth
685 f->stack_depth += arg_list->type->size;
687 // next arg
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 );
695 // builtin
696 f->s_type = ae_func_builtin;
698 return TRUE;
704 //-----------------------------------------------------------------------------
705 // name: type_engine_check_ugen_def_import()
706 // desc: ...
707 //-----------------------------------------------------------------------------
708 t_CKBOOL type_engine_check_ugen_def_import( t_Env info, Chuck_UGen_Info * ugen )
710 map<string, bool> params;
712 // look up the type
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) );
718 return FALSE;
721 // no return type
722 if( !ugen->tick )
724 EM_error2( ugen->linepos,
725 "imported ugen '%s.%s': no [tick] method defined",
726 S_name(info->name), ugen->name.c_str() );
727 return FALSE;
730 // add default
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];
740 // check the type
741 t_Type t = lookup_type( info, insert_symbol(param->type.c_str()) );
742 if( !t )
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() );
747 return FALSE;
750 // XXX - pld
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
755 // in the param list
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() );
761 return FALSE;
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() );
770 return FALSE;
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 );
782 return TRUE;
788 //-----------------------------------------------------------------------------
789 // name: type_engine_check_value_import()
790 // desc: ...
791 //-----------------------------------------------------------------------------
792 t_CKBOOL type_engine_check_value_import( t_Env info, S_Symbol name,
793 S_Symbol type, void * addr )
795 // lookup the value
796 if( lookup_value( info, name, FALSE ) )
798 EM_error2( 0,
799 "imported identifier '%s' is already in use in namespace '%s'",
800 name, S_name(info->name) );
801 return FALSE;
804 // lookup the type
805 t_Type t = lookup_type( info, type );
806 if( !t )
808 EM_error2( 0,
809 "imported identifier '%s.%s' has unrecognized type '%s'",
810 S_name(info->name), name, type );
811 return FALSE;
814 // insert value
815 S_enter( info->value, name, t );
816 // insert addr
817 S_enter( info->addr, name, addr );
819 return TRUE;
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 )
831 // push the scope
832 env->scope_push();
834 // type check the stmt_list
835 while( list )
837 if( !type_engine_check_stmt( env, list->stmt ) )
839 //env->out() << "type checker: statement in list does not type "
840 // << "check..." << endl;
841 return FALSE;
844 list = list->next;
847 // pop the scope
848 env->scope_pop();
850 return TRUE;
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 )
862 t_CKBOOL ret = TRUE;
864 if( !stmt )
865 return TRUE;
867 switch( stmt->s_type )
869 case ae_stmt_if:
870 // env->print( "stmt_if" );
871 ret = type_engine_check_if( env, &stmt->stmt_if );
872 break;
874 case ae_stmt_for:
875 // env->print( "stmt_for" );
876 ret = type_engine_check_for( env, &stmt->stmt_for );
877 break;
879 case ae_stmt_while:
880 // env->print( "stmt_while" );
881 ret = type_engine_check_while( env, &stmt->stmt_while );
882 break;
884 case ae_stmt_until:
885 // env->print( "stmt_until" );
886 ret = type_engine_check_until( env, &stmt->stmt_until );
887 break;
889 case ae_stmt_exp:
890 // evn->print( "stmt_exp" );
891 ret = ( type_engine_check_exp( env, stmt->stmt_exp ) != NULL );
892 break;
894 case ae_stmt_switch:
895 // env->print( "switch? not implemented" );
896 ret = type_engine_check_switch( env, &stmt->stmt_switch );
897 break;
899 case ae_stmt_return:
900 // env->print( "return" );
901 ret = type_engine_check_return( env, &stmt->stmt_return );
902 break;
904 case ae_stmt_case:
905 // env->print( "case" );
906 // ret = type_engine_check_case( env, &stmt->stmt_case );
907 break;
909 case ae_stmt_gotolabel:
910 // env->print( "gotolabel" );
911 // ok
912 break;
914 case ae_stmt_break:
915 // env->print( "break? not implemented" );
916 // ok here
917 break;
919 case ae_stmt_continue:
920 // env->print( "continue" );
921 // ok
922 break;
924 case ae_stmt_code:
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 );
929 break;
931 //case ae_stmt_func:
932 // // env->print( "func_def" );
933 // ret = type_engine_check_func_def( env, stmt->stmt_func );
934 // break;
936 default:
937 EM_error2( stmt->linepos,
938 "internal compiler error - no stmt type '%i'!", stmt->s_type );
939 break;
942 return ret;
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 )
954 a_Exp curr = exp;
956 while( curr )
958 curr->type = NULL;
960 switch( curr->s_type )
962 case ae_exp_binary:
963 curr->type = type_engine_check_exp_binary( env, &curr->binary );
964 break;
966 case ae_exp_unary:
967 curr->type = type_engine_check_exp_unary( env, &curr->unary );
968 break;
970 case ae_exp_cast:
971 curr->type = type_engine_check_exp_cast( env, &curr->cast );
972 break;
974 case ae_exp_postfix:
975 curr->type = type_engine_check_exp_postfix( env, &curr->postfix );
976 break;
978 case ae_exp_dur:
979 curr->type = type_engine_check_exp_dur( env, &curr->dur );
980 break;
982 case ae_exp_primary:
983 curr->type = type_engine_check_primary( env, &curr->primary );
984 break;
986 case ae_exp_array:
987 curr->type = type_engine_check_exp_array( env, &curr->array );
988 break;
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;
993 break;
995 case ae_exp_dot_member:
996 curr->type = type_engine_check_exp_dot_member( env, &curr->dot_member );
997 break;
999 case ae_exp_if:
1000 curr->type = type_engine_check_exp_if( env, &curr->exp_if );
1001 break;
1003 case ae_exp_decl:
1004 curr->type = type_engine_check_exp_decl( env, &curr->decl );
1005 break;
1007 case ae_exp_namespace:
1008 curr->type = type_engine_check_exp_namespace( env, &curr->name_space );
1009 break;
1011 /* case ae_exp_new:
1012 curr->exp_type = (t_Type)S_look( env->type, curr->a_new->type );
1013 break;
1016 default:
1017 EM_error2( curr->linepos, "internal compiler error - no expression '%i'",
1018 curr->s_type );
1019 return NULL;
1022 curr = curr->next;
1025 // return type
1026 return exp->type;
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 )
1038 t_Type type = NULL;
1040 switch( exp->s_type )
1042 case ae_primary_var:
1044 type = lookup_value( env, exp->var );
1045 if( !type )
1046 EM_error2( exp->linepos, "undefined variable '%s'",
1047 S_name(exp->var) );
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;
1061 break;
1063 case ae_primary_num:
1064 type = &t_int;
1065 break;
1067 case ae_primary_uint:
1068 type = &t_uint;
1069 break;
1071 case ae_primary_float:
1072 type = &t_float;
1073 break;
1075 case ae_primary_str:
1076 type = &t_string;
1077 break;
1079 case ae_primary_exp:
1080 type = type_engine_check_exp( env, exp->exp );
1081 break;
1083 default:
1084 EM_error2( exp->linepos,
1085 "internal compiler error - no primary expression '%i'", exp->s_type );
1086 break;
1089 return 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) )
1102 return &t_string;
1103 if( (left->type == te_dur) && (right->type == left->type) )
1104 return &t_dur;
1105 if( (left->type == te_dur) && (right->type == te_time) )
1106 return &t_time;
1107 if( left->type == __te_system_out__ )
1108 return left;
1109 if( right->type == __te_system_out__ )
1110 return left;
1111 if( left->type == te_int && right->type == te_midiout )
1112 return left;
1113 if( left->type == te_midiout && right->type == te_int )
1114 return left;
1115 if( left->type == te_midiin && right->type == te_int )
1116 return right;
1117 if( left->type != te_null && left->type == right->type )
1118 return right;
1120 // system
1121 if( left->type == te_string && right->type == __te_system_namespace__ )
1122 return right;
1124 // TODO: bad
1125 if( left->type == te_int && right->type == te_uint )
1126 return left;
1127 if( left->type == te_uint && right->type == te_int )
1128 return left;
1129 if( left->parent && right->parent &&
1130 left->parent->type == te_ugen && right->parent->type == te_ugen )
1131 return right;
1133 return NULL;
1139 //-----------------------------------------------------------------------------
1140 // name: type_engine_check_op_unchuck()
1141 // desc: ...
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 )
1147 return &t_ugen;
1149 return NULL;
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 )
1162 switch( op )
1164 case ae_op_chuck:
1165 return type_engine_check_op_chuck( env, left, right );
1166 break;
1167 case ae_op_unchuck:
1168 return type_engine_check_op_unchuck( env, left, right );
1169 break;
1170 case ae_op_plus:
1171 if( ( (left->type == te_dur) && (right->type == te_time) ) ||
1172 ( (left->type == te_time) && (right->type == te_dur) ) )
1173 return &t_time;
1174 case ae_op_minus:
1175 if( (left->type == te_time) && (right->type == te_dur) )
1176 return &t_time;
1177 if( (left->type == te_dur) && (right->type == left->type) )
1178 return &t_dur;
1179 if( (left->type == te_time) && (right->type == left->type) ) // XXX time - time = dur
1180 return &t_dur;
1181 case ae_op_times:
1182 case ae_op_divide:
1183 if( (left->type == te_dur) && (right->type == left->type) )
1184 return &t_float;
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) )
1190 return &t_float;
1191 if( (left->type == te_double) && (left->type == right->type) )
1192 return &t_double;
1193 if( (left->type == te_dur) && (right->type == te_float) )
1194 return &t_dur;
1196 case ae_op_lt:
1197 case ae_op_gt:
1198 case ae_op_le:
1199 case ae_op_ge:
1200 case ae_op_eq:
1201 case ae_op_neq:
1202 if( (left->type == te_int) && (left->type == right->type) )
1203 return &t_int;
1204 if( (left->type == te_uint) && (left->type == right->type) )
1205 return &t_int;
1206 if( (left->type == te_float) && (left->type == right->type) )
1207 return &t_int;
1208 if( (left->type == te_double) && (left->type == right->type) )
1209 return &t_int;
1210 if( (left->type == te_dur) && (left->type == right->type) )
1211 return &t_int;
1212 if( (left->type == te_time) && (left->type == right->type) )
1213 return &t_int;
1214 if( (left->type == te_int) && (right->type == te_uint) )
1215 return &t_int;
1216 if( (left->type == te_uint) && (right->type == te_int) )
1217 return &t_int;
1219 case ae_op_and:
1220 case ae_op_or:
1221 case ae_op_s_and:
1222 case ae_op_s_or:
1223 case ae_op_s_xor:
1224 if( op == ae_op_s_xor && ( (left->type == te_midiin) || (left->type == te_midiout) ) &&
1225 ( right->type == te_int ) )
1226 return left;
1227 case ae_op_shift_left:
1228 case ae_op_shift_right:
1229 case ae_op_percent:
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:
1237 case ae_op_s_chuck:
1238 case ae_op_at_chuck:
1239 if( (left->type == te_int) && (left->type == right->type) )
1240 return &t_int;
1241 if( (left->type == te_uint) && (left->type == right->type) )
1242 return &t_uint;
1243 if( (left->type == te_time) && (right->type == te_dur) )
1244 return &t_dur;
1245 if( (left->type == te_dur) && (right->type == te_dur) )
1246 return &t_dur;
1247 break;
1250 return NULL;
1256 //-----------------------------------------------------------------------------
1257 // name:
1258 // desc: ...
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;
1263 t_Type ret = NULL;
1265 // hack
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 )
1273 return NULL;
1275 while( cr )
1277 cl = binary->lhs;
1279 while( cl )
1281 ret = type_engine_check_op( env, binary->op, cl->type, cr->type );
1282 if( !ret )
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 );
1288 return NULL;
1291 // special case
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 )
1296 t_Env e = env;
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(),
1301 cl->primary.str );
1302 if( !dll )
1304 EM_error2( binary->linepos,
1305 "ChucK DLL load failed...\n [reason]: %s", e->vm->last_error() );
1306 return NULL;
1309 ((Chuck_DL_Query *)dll->query())->linepos = binary->linepos;
1310 type_engine_add_dll( e, dll, S_name(cr->name_space.name) );
1313 cl = cl->next;
1316 cr = cr->next;
1319 return ret;
1325 //-----------------------------------------------------------------------------
1326 // name: type_engine_check_exp_unary
1327 // desc: ...
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 );
1333 switch( unary->op )
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 --" );
1340 break;
1343 if( t->type == te_int || t->type == te_uint || t->type == te_float )
1344 return t;
1345 else
1347 EM_error2( unary->linepos, "bad type '%s' for unary operator '%s'",
1348 t->name, op2str(unary->op) );
1350 break;
1351 case ae_op_tilda:
1352 case ae_op_exclamation:
1353 case ae_op_minus:
1354 if( t->type == te_int || t->type == te_uint )
1355 return t;
1356 if( unary->op == ae_op_minus && t->type == te_float )
1357 return t;
1358 else
1360 EM_error2( unary->linepos, "bad type '%s' for unary operator '%s'",
1361 t->name, op2str(unary->op) );
1363 break;
1364 case ae_op_spork:
1365 if( unary->exp->s_type == ae_exp_func_call )
1366 return &t_int;
1367 else
1369 EM_error2( unary->linepos, "only function calls can be sporked" );
1371 break;
1372 default:
1373 EM_error2( unary->linepos, "unrecognized unary operator '%s'",
1374 op2str(unary->op) );
1375 break;
1378 return NULL;
1384 //-----------------------------------------------------------------------------
1385 // name: type_engine_check_cast_valid()
1386 // desc: ...
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;
1394 return FALSE;
1400 //-----------------------------------------------------------------------------
1401 // name: type_engine_check_exp_cast()
1402 // desc: ...
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 );
1410 if( !t2 )
1412 EM_error2( cast->linepos,
1413 "casting to unknown type '%s'...", S_name(cast->type) );
1414 return NULL;
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 );
1422 return NULL;
1425 return t2;
1431 //-----------------------------------------------------------------------------
1432 // name: type_engine_check_exp_postfix
1433 // desc: ...
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 );
1439 if( !t )
1440 return NULL;
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" );
1449 break;
1452 if( t->type == te_int || t->type == te_uint || t->type == te_float )
1453 return t;
1454 else
1456 EM_error2( postfix->linepos, "bad type '%s' for unary operator '%s'",
1457 t->name, op2str(postfix->op) );
1459 break;
1460 default:
1461 EM_error2( postfix->linepos,
1462 "internal compiler error - unrecognized postfix operator '%s'", op2str(postfix->op) );
1463 break;
1466 // start here
1467 return NULL;
1473 //-----------------------------------------------------------------------------
1474 // name: type_engine_check_exp_dur
1475 // desc: ...
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 );
1482 // check here
1483 if( !base || !unit )
1484 return NULL;
1486 // check
1487 if( base->type != te_float && base->type != te_int )
1489 EM_error2( dur->base->linepos,
1490 "base type '%s' illegal in dur expression",
1491 base->name );
1492 return NULL;
1495 // check
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'",
1500 unit->name );
1501 return NULL;
1504 return &t_dur;
1510 //-----------------------------------------------------------------------------
1511 // name: type_engine_check_exp_array
1512 // desc: ...
1513 //-----------------------------------------------------------------------------
1514 t_Type type_engine_check_exp_array( t_Env env, a_Exp_Array array )
1516 return NULL;
1522 //-----------------------------------------------------------------------------
1523 // name: type_engine_check_exp_func_call
1524 // desc: ...
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;
1532 t_Type a = &t_void;
1534 if( f->type != te_function )
1536 EM_error2( func_call->linepos, "function call using a non-function value" );
1537 return NULL;
1540 c_str name = "()";
1541 if( func_call->func->s_type == ae_exp_primary )
1543 if( func_call->func->primary.s_type == ae_primary_var )
1545 // find func
1546 func = lookup_func( env, func_call->func->primary.var );
1547 if( !func )
1549 EM_error2( func_call->linepos,
1550 "no function named '%s' defined", S_name(func_call->func->primary.var) );
1551 return NULL;
1554 else
1556 EM_error2( func_call->linepos, "function call using illegal f-value" );
1557 return NULL;
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
1568 if( !e || !s )
1570 EM_error2( func_call->linepos, "type checker: missing env/symbol in func call" );
1571 return NULL;
1574 // find func
1575 func = lookup_func( e, s );
1576 if( !func )
1578 EM_error2( func_call->linepos,
1579 "no function named '%s' defined in namespace/class '%s'",
1580 S_name(s), S_name(e->name) );
1581 return NULL;
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;
1597 // check arguments
1598 while( e )
1600 if( e1 == NULL )
1602 EM_error2( func_call->linepos,
1603 "extra argument(s) in function call '%s' %i %s",
1604 name, e->s_type, e->type->name );
1605 return NULL;
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 );
1613 return NULL;
1616 e = e->next;
1617 e1 = e1->next;
1618 count++;
1621 if( e1 != NULL )
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) );
1626 return NULL;
1629 return func->ret_type;
1635 //-----------------------------------------------------------------------------
1636 // name: type_engine_check_exp_dot_member
1637 // desc: ...
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 );
1643 if( !t_base )
1644 return NULL;
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 );
1650 if( !info )
1652 EM_error2( member->linepos,
1653 "cannot find namespace '%s'",
1654 S_name(env->nspc_name) );
1655 return NULL;
1658 // find the member
1659 t_Type t_member = lookup_value( info, member->id, FALSE );
1660 if( !t_member )
1662 EM_error2( member->linepos,
1663 "cannot find member '%s' in namespace '%s'",
1664 S_name(member->id), S_name(info->name) );
1665 return NULL;
1668 // set the member
1669 env->child = info;
1670 env->nspc_name = member->id;
1672 return t_member;
1674 else if( isa( t_base, &t_ugen ) )
1676 // look for ugen
1677 Chuck_UGen_Info * info = lookup_ugen( env, insert_symbol(t_base->name), FALSE );
1678 if( !info )
1680 EM_error2( member->linepos,
1681 "cannot find unit generator '%s'",
1682 t_base->name );
1683 return NULL;
1686 // find member
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) );
1693 return NULL;
1696 env->nspc_name = NULL;
1698 // look for the type
1699 t_Type t_param = lookup_type( env, insert_symbol(param.type.c_str()) );
1700 if( !t_param )
1702 EM_error2( member->linepos,
1703 "type checker: internal error: cannot find param type '%s'",
1704 param.type.c_str() );
1705 return NULL;
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() );
1717 return NULL;
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) );
1725 return NULL;
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) );
1732 return NULL;
1735 return t;
1737 else
1739 EM_error2( member->linepos,
1740 "internal error: class namespace not impl" );
1741 return NULL;
1744 return NULL;
1750 //-----------------------------------------------------------------------------
1751 // name: type_engine_check_exp_if
1752 // desc: ...
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 );
1760 return NULL;
1766 //-----------------------------------------------------------------------------
1767 // name: type_engine_check_exp_decl()
1768 // desc: ...
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!" );
1779 t = &t_array;
1780 return NULL;
1782 else
1784 // look up the type in the type binding
1785 t = lookup_type( env, decl->type );
1787 // type there?
1788 if( t == NULL )
1790 // error - no type
1791 EM_error2( decl->linepos, "undefined type '%s'",
1792 S_name(decl->type) );
1793 return NULL;
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) );
1804 return NULL;
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 );
1812 return t;
1818 //-----------------------------------------------------------------------------
1819 // name: type_engine_check_exp_namespace( )
1820 // desc: ...
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;
1840 return FALSE;
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;
1847 return FALSE;
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;
1855 return FALSE;
1859 return TRUE;
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;
1875 return FALSE;
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;
1882 return FALSE;
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;
1889 return FALSE;
1891 // check body
1892 if( !type_engine_check_stmt( env, stmt->body ) )
1894 // env->out() << "type checker: bad type in for body" << endl;
1895 return FALSE;
1898 return TRUE;
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;
1925 return FALSE;
1928 if( !type_engine_check_stmt( env, stmt->body ) )
1930 // env->out() << "type checker: while statement does not type check" << endl;
1931 return FALSE;
1934 return TRUE;
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;
1949 return FALSE;
1952 if( !type_engine_check_stmt( env, stmt->body ) )
1954 // env->out() << "type checker: while statement does not type check" << endl;
1955 return FALSE;
1958 return TRUE;
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" );
1975 return FALSE;
1978 if( stmt->val )
1979 ret_type = type_engine_check_exp( env, stmt->val );
1980 else
1981 ret_type = &t_void;
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 );
1988 return FALSE;
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 )
2003 return TRUE;
2009 //-----------------------------------------------------------------------------
2010 // name: lookup_type()
2011 // desc: ...
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 );
2018 return t;
2024 //-----------------------------------------------------------------------------
2025 // name: lookup_value()
2026 // desc: ...
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 );
2033 return t;
2039 //-----------------------------------------------------------------------------
2040 // name: lookup_func()
2041 // desc: ...
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 );
2048 return f;
2054 //-----------------------------------------------------------------------------
2055 // name: lookup_ugen()
2056 // desc: ...
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 );
2063 return ugen;
2069 //-----------------------------------------------------------------------------
2070 // name: lookup_namespace()
2071 // desc: ...
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 );
2078 return e;
2084 //-----------------------------------------------------------------------------
2085 // name: lookup_addr()
2086 // desc: ...
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 );
2093 return v;
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 )
2105 a_Exp curr = exp;
2106 t_CKBOOL val = TRUE;
2108 while( curr && val )
2110 val = FALSE;
2111 switch( curr->s_type )
2113 case ae_exp_primary:
2114 val = type_engine_check_primary_mem( env, &curr->primary );
2115 break;
2117 case ae_exp_array:
2118 val = type_engine_check_exp_array_mem( env, &curr->array );
2119 break;
2121 case ae_exp_func_call:
2122 val = type_engine_check_exp_func_call_mem( env, &curr->func_call );
2123 break;
2125 case ae_exp_dot_member:
2126 val = type_engine_check_exp_dot_member_mem( env, &curr->dot_member );
2127 break;
2130 curr = curr->next;
2133 // return type
2134 return val;
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 );
2152 break;
2154 case ae_primary_exp:
2155 val = type_engine_check_exp_mem( env, exp->exp );
2156 break;
2158 default:
2159 // env->out() << "type checker: bad primary [mem] values..." << endl;
2160 break;
2163 return val;
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 )
2175 return FALSE;
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 )
2187 return FALSE;
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 )
2199 return FALSE;