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_scan.cpp
27 // desc: chuck type-system / type-checker pre-scan
29 // author: Ge Wang (gewang@cs.princeton.edu)
30 // Perry R. Cook (prc@cs.princeton.edu)
31 // date: Summer 2005 - original
32 //-----------------------------------------------------------------------------
33 #include "chuck_type.h"
34 #include "chuck_scan.h"
35 #include "chuck_errmsg.h"
37 #include "util_string.h"
44 //-----------------------------------------------------------------------------
45 // function prototypes
46 //-----------------------------------------------------------------------------
47 t_CKBOOL
type_engine_scan0_class_def( Chuck_Env
* env
, a_Class_Def class_def
);
49 t_CKBOOL
type_engine_scan1_stmt_list( Chuck_Env
* env
, a_Stmt_List list
);
50 t_CKBOOL
type_engine_scan1_stmt( Chuck_Env
* env
, a_Stmt stmt
);
51 t_CKBOOL
type_engine_scan1_if( Chuck_Env
* env
, a_Stmt_If stmt
);
52 t_CKBOOL
type_engine_scan1_for( Chuck_Env
* env
, a_Stmt_For stmt
);
53 t_CKBOOL
type_engine_scan1_while( Chuck_Env
* env
, a_Stmt_While stmt
);
54 t_CKBOOL
type_engine_scan1_until( Chuck_Env
* env
, a_Stmt_Until stmt
);
55 t_CKBOOL
type_engine_scan1_loop( Chuck_Env
* env
, a_Stmt_Loop stmt
);
56 t_CKBOOL
type_engine_scan1_break( Chuck_Env
* env
, a_Stmt_Break br
);
57 t_CKBOOL
type_engine_scan1_continue( Chuck_Env
* env
, a_Stmt_Continue cont
);
58 t_CKBOOL
type_engine_scan1_return( Chuck_Env
* env
, a_Stmt_Return stmt
);
59 t_CKBOOL
type_engine_scan1_switch( Chuck_Env
* env
, a_Stmt_Switch stmt
);
60 t_CKBOOL
type_engine_scan1_exp( Chuck_Env
* env
, a_Exp exp
);
61 t_CKBOOL
type_engine_scan1_exp_binary( Chuck_Env
* env
, a_Exp_Binary binary
);
62 t_CKBOOL
type_engine_scan1_op( Chuck_Env
* env
, ae_Operator op
, a_Exp lhs
, a_Exp rhs
, a_Exp_Binary binary
);
63 t_CKBOOL
type_engine_scan1_op_chuck( Chuck_Env
* env
, a_Exp lhs
, a_Exp rhs
, a_Exp_Binary binary
);
64 t_CKBOOL
type_engine_scan1_op_unchuck( Chuck_Env
* env
, a_Exp lhs
, a_Exp rhs
);
65 t_CKBOOL
type_engine_scan1_op_upchuck( Chuck_Env
* env
, a_Exp lhs
, a_Exp rhs
);
66 t_CKBOOL
type_engine_scan1_op_at_chuck( Chuck_Env
* env
, a_Exp lhs
, a_Exp rhs
);
67 t_CKBOOL
type_engine_scan1_exp_unary( Chuck_Env
* env
, a_Exp_Unary unary
);
68 t_CKBOOL
type_engine_scan1_exp_primary( Chuck_Env
* env
, a_Exp_Primary exp
);
69 t_CKBOOL
type_engine_scan1_exp_array_lit( Chuck_Env
* env
, a_Exp_Primary exp
);
70 t_CKBOOL
type_engine_scan1_exp_cast( Chuck_Env
* env
, a_Exp_Cast cast
);
71 t_CKBOOL
type_engine_scan1_exp_postfix( Chuck_Env
* env
, a_Exp_Postfix postfix
);
72 t_CKBOOL
type_engine_scan1_exp_dur( Chuck_Env
* env
, a_Exp_Dur dur
);
73 t_CKBOOL
type_engine_scan1_exp_array( Chuck_Env
* env
, a_Exp_Array array
);
74 t_CKBOOL
type_engine_scan1_exp_func_call( Chuck_Env
* env
, a_Exp_Func_Call func_call
);
75 t_CKBOOL
type_engine_scan1_exp_func_call( Chuck_Env
* env
, a_Exp exp_func
, a_Exp args
,
76 t_CKFUNC
& ck_func
, int linepos
);
77 t_CKBOOL
type_engine_scan1_exp_dot_member( Chuck_Env
* env
, a_Exp_Dot_Member member
);
78 t_CKBOOL
type_engine_scan1_exp_if( Chuck_Env
* env
, a_Exp_If exp_if
);
79 t_CKBOOL
type_engine_scan1_exp_decl( Chuck_Env
* env
, a_Exp_Decl decl
);
80 t_CKBOOL
type_engine_scan1_array_subscripts( Chuck_Env
* env
, a_Exp exp_list
);
81 t_CKBOOL
type_engine_scan1_cast_valid( Chuck_Env
* env
, t_CKTYPE to
, t_CKTYPE from
);
82 t_CKBOOL
type_engine_scan1_code_segment( Chuck_Env
* env
, a_Stmt_Code stmt
, t_CKBOOL push
= TRUE
);
83 t_CKBOOL
type_engine_scan1_func_def( Chuck_Env
* env
, a_Func_Def func_def
);
84 t_CKBOOL
type_engine_scan1_class_def( Chuck_Env
* env
, a_Class_Def class_def
);
86 t_CKBOOL
type_engine_scan2_stmt_list( Chuck_Env
* env
, a_Stmt_List list
);
87 t_CKBOOL
type_engine_scan2_stmt( Chuck_Env
* env
, a_Stmt stmt
);
88 t_CKBOOL
type_engine_scan2_if( Chuck_Env
* env
, a_Stmt_If stmt
);
89 t_CKBOOL
type_engine_scan2_for( Chuck_Env
* env
, a_Stmt_For stmt
);
90 t_CKBOOL
type_engine_scan2_while( Chuck_Env
* env
, a_Stmt_While stmt
);
91 t_CKBOOL
type_engine_scan2_loop( Chuck_Env
* env
, a_Stmt_Loop stmt
);
92 t_CKBOOL
type_engine_scan2_until( Chuck_Env
* env
, a_Stmt_Until stmt
);
93 t_CKBOOL
type_engine_scan2_break( Chuck_Env
* env
, a_Stmt_Break br
);
94 t_CKBOOL
type_engine_scan2_continue( Chuck_Env
* env
, a_Stmt_Continue cont
);
95 t_CKBOOL
type_engine_scan2_return( Chuck_Env
* env
, a_Stmt_Return stmt
);
96 t_CKBOOL
type_engine_scan2_switch( Chuck_Env
* env
, a_Stmt_Switch stmt
);
97 t_CKBOOL
type_engine_scan2_exp( Chuck_Env
* env
, a_Exp exp
);
98 t_CKBOOL
type_engine_scan2_exp_binary( Chuck_Env
* env
, a_Exp_Binary binary
);
99 t_CKBOOL
type_engine_scan2_op( Chuck_Env
* env
, ae_Operator op
, a_Exp lhs
, a_Exp rhs
, a_Exp_Binary binary
);
100 t_CKBOOL
type_engine_scan2_op_chuck( Chuck_Env
* env
, a_Exp lhs
, a_Exp rhs
, a_Exp_Binary binary
);
101 t_CKBOOL
type_engine_scan2_op_unchuck( Chuck_Env
* env
, a_Exp lhs
, a_Exp rhs
);
102 t_CKBOOL
type_engine_scan2_op_upchuck( Chuck_Env
* env
, a_Exp lhs
, a_Exp rhs
);
103 t_CKBOOL
type_engine_scan2_op_at_chuck( Chuck_Env
* env
, a_Exp lhs
, a_Exp rhs
);
104 t_CKBOOL
type_engine_scan2_exp_unary( Chuck_Env
* env
, a_Exp_Unary unary
);
105 t_CKBOOL
type_engine_scan2_exp_primary( Chuck_Env
* env
, a_Exp_Primary exp
);
106 t_CKBOOL
type_engine_scan2_exp_array_lit( Chuck_Env
* env
, a_Exp_Primary exp
);
107 t_CKBOOL
type_engine_scan2_exp_cast( Chuck_Env
* env
, a_Exp_Cast cast
);
108 t_CKBOOL
type_engine_scan2_exp_postfix( Chuck_Env
* env
, a_Exp_Postfix postfix
);
109 t_CKBOOL
type_engine_scan2_exp_dur( Chuck_Env
* env
, a_Exp_Dur dur
);
110 t_CKBOOL
type_engine_scan2_exp_array( Chuck_Env
* env
, a_Exp_Array array
);
111 t_CKBOOL
type_engine_scan2_exp_func_call( Chuck_Env
* env
, a_Exp_Func_Call func_call
);
112 t_CKBOOL
type_engine_scan2_exp_func_call( Chuck_Env
* env
, a_Exp exp_func
, a_Exp args
,
113 t_CKFUNC
& ck_func
, int linepos
);
114 t_CKBOOL
type_engine_scan2_exp_dot_member( Chuck_Env
* env
, a_Exp_Dot_Member member
);
115 t_CKBOOL
type_engine_scan2_exp_if( Chuck_Env
* env
, a_Exp_If exp_if
);
116 t_CKBOOL
type_engine_scan2_exp_decl( Chuck_Env
* env
, a_Exp_Decl decl
);
117 t_CKBOOL
type_engine_scan2_array_subscripts( Chuck_Env
* env
, a_Exp exp_list
);
118 t_CKBOOL
type_engine_scan2_cast_valid( Chuck_Env
* env
, t_CKTYPE to
, t_CKTYPE from
);
119 t_CKBOOL
type_engine_scan2_code_segment( Chuck_Env
* env
, a_Stmt_Code stmt
, t_CKBOOL push
= TRUE
);
120 t_CKBOOL
type_engine_scan2_func_def( Chuck_Env
* env
, a_Func_Def func_def
);
121 t_CKBOOL
type_engine_scan2_class_def( Chuck_Env
* env
, a_Class_Def class_def
);
122 t_CKBOOL
type_engine_scan2_func_def( Chuck_Env
* env
, a_Func_Def func_def
);
123 t_CKBOOL
type_engine_scan2_class_def( Chuck_Env
* env
, a_Class_Def class_def
);
128 //-----------------------------------------------------------------------------
129 // name: type_engine_scan0_prog()
130 // desc: data in env should be ready : type discovery
131 //-----------------------------------------------------------------------------
132 t_CKBOOL
type_engine_scan0_prog( Chuck_Env
* env
, a_Program prog
,
133 te_HowMuch how_much
)
141 EM_log( CK_LOG_FINER
, "(pass 0) type discovery scan '%s'...",
142 env
->context
->filename
.c_str() );
146 EM_log( CK_LOG_FINER
, "target: %s", howmuch2str( how_much
) );
148 // go through each of the program sections
151 switch( prog
->section
->s_type
)
153 case ae_section_stmt
:
157 case ae_section_func
:
161 case ae_section_class
:
162 // if no classes, then skip
163 if( how_much
== te_do_no_classes
) break;
164 // make global, if marked public
165 if( prog
->section
->class_def
->decl
== ae_key_public
)
167 // make sure the context has no public class
168 if( env
->context
->public_class_def
!= NULL
)
170 EM_error2( prog
->section
->class_def
->linepos
,
171 "more than one 'public' class defined..." );
177 prog
->section
->class_def
->home
= env
->global();
179 env
->context
->public_class_def
= prog
->section
->class_def
;
181 // scan the class definition
182 ret
= type_engine_scan0_class_def( env
, prog
->section
->class_def
);
186 EM_error2( prog
->linepos
,
187 "internal error: unrecognized program section in type checker pre-scan..." );
204 //-----------------------------------------------------------------------------
205 // name: type_engine_scan0_class_def()
206 // desc: add defined class to env - this is the main goal of scan0
207 //-----------------------------------------------------------------------------
208 t_CKBOOL
type_engine_scan0_class_def( Chuck_Env
* env
, a_Class_Def class_def
)
210 // make new type for class def
211 t_CKTYPE the_class
= NULL
;
215 a_Class_Body body
= class_def
->body
;
218 EM_log( CK_LOG_FINER
, "scanning class definition '%s'...",
219 S_name(class_def
->name
->xid
) );
223 // if nspc is attached to class_def, that means the class_def is to be
224 // put in that namespace. this is usually the case when doing import
225 if( class_def
->home
!= NULL
)
228 EM_log( CK_LOG_FINER
, "target namespace: '%s'",
229 class_def
->home
->name
.c_str() );
230 // set the new type as current
231 env
->nspc_stack
.push_back( env
->curr
);
232 env
->curr
= class_def
->home
;
235 // make sure class not already in namespace
236 if( env
->curr
->lookup_type( class_def
->name
->xid
, FALSE
) )
238 EM_error2( class_def
->name
->linepos
,
239 "class/type '%s' is already defined in namespace '%s'",
240 S_name(class_def
->name
->xid
), env
->curr
->name
.c_str() );
241 ret
= FALSE
; goto done
;
245 if( type_engine_check_reserved( env
, class_def
->name
->xid
, class_def
->name
->linepos
) )
247 EM_error2( class_def
->name
->linepos
, "...in class definition '%s'",
248 S_name(class_def
->name
->xid
) );
249 ret
= FALSE
; goto done
;
253 assert( env
->context
!= NULL
);
254 the_class
= env
->context
->new_Chuck_Type();
256 SAFE_ADD_REF( the_class
);
258 the_class
->xid
= te_user
;
259 the_class
->name
= S_name(class_def
->name
->xid
);
260 the_class
->owner
= env
->curr
;
261 the_class
->array_depth
= 0;
262 the_class
->size
= sizeof(void *);
263 the_class
->obj_size
= 0; // TODO:
264 the_class
->info
= env
->context
->new_Chuck_Namespace();
265 SAFE_ADD_REF( the_class
->info
);
266 the_class
->info
->name
= the_class
->name
;
267 // if public class, then set parent to context
268 // ... allowing the class to address current context
269 if( env
->context
->public_class_def
== class_def
)
270 { the_class
->info
->parent
= env
->context
->nspc
; }
271 else { the_class
->info
->parent
= env
->curr
; }
272 // TODO: add ref to the parent?
273 the_class
->func
= NULL
;
274 the_class
->def
= class_def
;
276 the_class
->info
->pre_ctor
= new Chuck_VM_Code
;
277 SAFE_ADD_REF( the_class
->info
->pre_ctor
);
279 env
->curr
->type
.add( the_class
->name
, the_class
); // URGENT: make this global
281 the_class
->is_complete
= FALSE
;
283 // set the new type as current
284 env
->nspc_stack
.push_back( env
->curr
);
285 env
->curr
= the_class
->info
;
286 // push the class def
287 env
->class_stack
.push_back( env
->class_def
);
288 env
->class_def
= the_class
;
289 // reset the nest list
290 env
->class_scope
= 0;
292 // type check the body
296 switch( body
->section
->s_type
)
298 case ae_section_stmt
:
301 case ae_section_func
:
304 case ae_section_class
:
306 ret
= type_engine_scan0_class_def( env
, body
->section
->class_def
);
310 // move to the next section
316 env
->class_def
= env
->class_stack
.back();
317 env
->class_stack
.pop_back();
319 env
->curr
= env
->nspc_stack
.back();
320 env
->nspc_stack
.pop_back();
322 // if things checked out
325 Chuck_Value
* value
= NULL
;
326 Chuck_Type
* type
= NULL
;
329 type
= t_class
.copy( env
);
330 type
->actual_type
= the_class
;
331 value
= env
->context
->new_Chuck_Value( type
, the_class
->name
);
332 value
->owner
= env
->curr
;
333 value
->is_const
= TRUE
;
334 value
->is_member
= FALSE
;
336 env
->curr
->value
.add( the_class
->name
, value
);
339 class_def
->type
= the_class
;
342 // if nspc is attached to class_def, that means the class_def is to be
343 // put in that namespace. this is usually the case when doing import
344 // we undo that extra namespace layer here...
345 if( class_def
->home
!= NULL
)
348 env
->curr
= env
->nspc_stack
.back();
349 env
->nspc_stack
.pop_back();
351 else // set the current namespace as home
354 class_def
->home
= env
->curr
;
368 //-----------------------------------------------------------------------------
369 // name: type_engine_scan1_prog()
370 // desc: data in env should be ready
371 //-----------------------------------------------------------------------------
372 t_CKBOOL
type_engine_scan1_prog( Chuck_Env
* env
, a_Program prog
,
373 te_HowMuch how_much
)
381 EM_log( CK_LOG_FINER
, "(pass 1) type resolution scan '%s'...",
382 env
->context
->filename
.c_str() );
386 EM_log( CK_LOG_FINER
, "target: %s", howmuch2str( how_much
) );
388 // go through each of the program sections
391 switch( prog
->section
->s_type
)
393 case ae_section_stmt
:
394 // if only classes, then skip
395 if( how_much
== te_do_classes_only
) break;
396 // scan the statements
397 ret
= type_engine_scan1_stmt_list( env
, prog
->section
->stmt_list
);
400 case ae_section_func
:
401 // if only classes, then skip
402 if( how_much
== te_do_classes_only
) break;
403 // scan the function definition
404 ret
= type_engine_scan1_func_def( env
, prog
->section
->func_def
);
407 case ae_section_class
:
408 // if no classes, then skip
409 if( how_much
== te_do_no_classes
) break;
410 // scan the class definition
411 ret
= type_engine_scan1_class_def( env
, prog
->section
->class_def
);
415 EM_error2( prog
->linepos
,
416 "internal error: unrecognized program section in type checker pre-scan..." );
433 //-----------------------------------------------------------------------------
434 // name: type_engine_scan1_stmt_list()
436 //-----------------------------------------------------------------------------
437 t_CKBOOL
type_engine_scan1_stmt_list( Chuck_Env
* env
, a_Stmt_List list
)
439 // type check the stmt_list
442 // the current statement
443 if( !type_engine_scan1_stmt( env
, list
->stmt
) )
446 // advance to the next statement
456 //-----------------------------------------------------------------------------
457 // name: type_engine_scan1_stmt(()
459 //-----------------------------------------------------------------------------
460 t_CKBOOL
type_engine_scan1_stmt( Chuck_Env
* env
, a_Stmt stmt
)
462 t_CKBOOL ret
= FALSE
;
468 switch( stmt
->s_type
)
471 // count scope to help determine class member
473 env
->curr
->value
.push();
474 ret
= type_engine_scan1_if( env
, &stmt
->stmt_if
);
475 env
->curr
->value
.pop();
481 env
->curr
->value
.push();
482 ret
= type_engine_scan1_for( env
, &stmt
->stmt_for
);
483 env
->curr
->value
.pop();
489 env
->curr
->value
.push();
490 ret
= type_engine_scan1_while( env
, &stmt
->stmt_while
);
491 env
->curr
->value
.pop();
497 env
->curr
->value
.push();
498 ret
= type_engine_scan1_until( env
, &stmt
->stmt_until
);
499 env
->curr
->value
.pop();
505 env
->curr
->value
.push();
506 ret
= type_engine_scan1_loop( env
, &stmt
->stmt_loop
);
507 env
->curr
->value
.pop();
512 ret
= type_engine_scan1_exp( env
, stmt
->stmt_exp
);
516 ret
= type_engine_scan1_return( env
, &stmt
->stmt_return
);
521 ret
= type_engine_scan1_code_segment( env
, &stmt
->stmt_code
);
526 ret
= type_engine_scan1_break( env
, &stmt
->stmt_break
);
529 case ae_stmt_continue
:
530 ret
= type_engine_scan1_continue( env
, &stmt
->stmt_continue
);
535 ret
= type_engine_scan1_switch( env
, &stmt
->stmt_switch
);
540 // ret = type_engine_scan1_case( env, &stmt->stmt_case );
543 case ae_stmt_gotolabel
:
544 // ret = type_engine_scan1_gotolabel( env, &stmt->goto_label );
548 EM_error2( stmt
->linepos
,
549 "internal compiler error (pre-scan) - no stmt type '%i'!", stmt
->s_type
);
560 //-----------------------------------------------------------------------------
561 // name: type_engine_scan1_if()
563 //-----------------------------------------------------------------------------
564 t_CKBOOL
type_engine_scan1_if( Chuck_Env
* env
, a_Stmt_If stmt
)
566 // check the conditional
567 if( !type_engine_scan1_exp( env
, stmt
->cond
) )
570 // TODO: ensure that conditional has valid type
573 if( !type_engine_scan1_stmt( env
, stmt
->if_body
) )
576 // check else, if there is one
577 if( stmt
->else_body
)
578 if( !type_engine_scan1_stmt( env
, stmt
->else_body
) )
587 //-----------------------------------------------------------------------------
588 // name: type_engine_scan1_for()
590 //-----------------------------------------------------------------------------
591 t_CKBOOL
type_engine_scan1_for( Chuck_Env
* env
, a_Stmt_For stmt
)
594 if( !type_engine_scan1_stmt( env
, stmt
->c1
) )
597 // check the conditional
598 if( !type_engine_scan1_stmt( env
, stmt
->c2
) )
601 // TODO: same as if - check conditional type valid
604 if( stmt
->c3
&& !type_engine_scan1_exp( env
, stmt
->c3
) )
608 if( !type_engine_scan1_stmt( env
, stmt
->body
) )
617 //-----------------------------------------------------------------------------
618 // name: type_engine_scan1_while()
620 //-----------------------------------------------------------------------------
621 t_CKBOOL
type_engine_scan1_while( Chuck_Env
* env
, a_Stmt_While stmt
)
623 // check the conditional
624 if( !type_engine_scan1_exp( env
, stmt
->cond
) )
627 // TODO: same as if - ensure the type in conditional is valid
630 if( !type_engine_scan1_stmt( env
, stmt
->body
) )
639 //-----------------------------------------------------------------------------
640 // name: type_engine_scan1_until()
642 //-----------------------------------------------------------------------------
643 t_CKBOOL
type_engine_scan1_until( Chuck_Env
* env
, a_Stmt_Until stmt
)
645 // check the conditional
646 if( !type_engine_scan1_exp( env
, stmt
->cond
) )
649 // TODO: same as if - ensure the type in conditional is valid
652 if( !type_engine_scan1_stmt( env
, stmt
->body
) )
661 //-----------------------------------------------------------------------------
662 // name: type_engine_scan1_loop()
664 //-----------------------------------------------------------------------------
665 t_CKBOOL
type_engine_scan1_loop( Chuck_Env
* env
, a_Stmt_Loop stmt
)
667 // check the conditional
668 if( !type_engine_scan1_exp( env
, stmt
->cond
) )
671 // TODO: same as if - ensure the type in conditional is valid
674 if( !type_engine_scan1_stmt( env
, stmt
->body
) )
683 //-----------------------------------------------------------------------------
684 // name: type_engine_scan1_switch()
686 //-----------------------------------------------------------------------------
687 t_CKBOOL
type_engine_scan1_switch( Chuck_Env
* env
, a_Stmt_Switch stmt
)
689 // TODO: implement this
690 EM_error2( stmt
->linepos
, "switch not implemented..." );
698 //-----------------------------------------------------------------------------
699 // name: type_engine_scan1_break()
701 //-----------------------------------------------------------------------------
702 t_CKBOOL
type_engine_scan1_break( Chuck_Env
* env
, a_Stmt_Break br
)
710 //-----------------------------------------------------------------------------
711 // name: type_engine_scan1_continue()
713 //-----------------------------------------------------------------------------
714 t_CKBOOL
type_engine_scan1_continue( Chuck_Env
* env
, a_Stmt_Continue cont
)
722 //-----------------------------------------------------------------------------
723 // name: type_engine_scan1_return()
725 //-----------------------------------------------------------------------------
726 t_CKBOOL
type_engine_scan1_return( Chuck_Env
* env
, a_Stmt_Return stmt
)
728 t_CKBOOL ret
= FALSE
;
730 // check the type of the return
732 ret
= type_engine_scan1_exp( env
, stmt
->val
);
742 //-----------------------------------------------------------------------------
743 // name: type_engine_scan1_code_segment()
745 //-----------------------------------------------------------------------------
746 t_CKBOOL
type_engine_scan1_code_segment( Chuck_Env
* env
, a_Stmt_Code stmt
,
752 if( push
) env
->curr
->value
.push(); // env->context->nspc.value.push();
754 t_CKBOOL t
= type_engine_scan1_stmt_list( env
, stmt
->stmt_list
);
756 if( push
) env
->curr
->value
.pop(); // env->context->nspc.value.pop();
766 //-----------------------------------------------------------------------------
767 // name: type_engine_scan1_exp()
769 //-----------------------------------------------------------------------------
770 t_CKBOOL
type_engine_scan1_exp( Chuck_Env
* env
, a_Exp exp
)
775 // loop through parallel expressions
778 // examine the syntax
779 switch( curr
->s_type
)
782 ret
= type_engine_scan1_exp_binary( env
, &curr
->binary
);
786 ret
= type_engine_scan1_exp_unary( env
, &curr
->unary
);
790 ret
= type_engine_scan1_exp_cast( env
, &curr
->cast
);
794 ret
= type_engine_scan1_exp_postfix( env
, &curr
->postfix
);
798 ret
= type_engine_scan1_exp_dur( env
, &curr
->dur
);
802 ret
= type_engine_scan1_exp_primary( env
, &curr
->primary
);
806 ret
= type_engine_scan1_exp_array( env
, &curr
->array
);
809 case ae_exp_func_call
:
810 ret
= type_engine_scan1_exp_func_call( env
, &curr
->func_call
);
813 case ae_exp_dot_member
:
814 ret
= type_engine_scan1_exp_dot_member( env
, &curr
->dot_member
);
818 ret
= type_engine_scan1_exp_if( env
, &curr
->exp_if
);
822 ret
= type_engine_scan1_exp_decl( env
, &curr
->decl
);
826 EM_error2( curr
->linepos
,
827 "internal compiler error - no expression type '%i'...",
836 // advance to next expression
847 //-----------------------------------------------------------------------------
848 // name: type_engine_scan1_exp_binary()
850 //-----------------------------------------------------------------------------
851 t_CKBOOL
type_engine_scan1_exp_binary( Chuck_Env
* env
, a_Exp_Binary binary
)
853 a_Exp cl
= binary
->lhs
, cr
= binary
->rhs
;
855 // type check the lhs and rhs
856 t_CKBOOL left
= type_engine_scan1_exp( env
, cl
);
857 t_CKBOOL right
= type_engine_scan1_exp( env
, cr
);
859 // if either fails, then return FALSE
860 if( !left
|| !right
)
866 // type check the pair
867 if( !type_engine_scan1_op( env
, binary
->op
, cl
, cr
, binary
) )
879 //-----------------------------------------------------------------------------
880 // name: type_engine_scan1_op()
882 //-----------------------------------------------------------------------------
883 t_CKBOOL
type_engine_scan1_op( Chuck_Env
* env
, ae_Operator op
, a_Exp lhs
, a_Exp rhs
,
884 a_Exp_Binary binary
)
886 // TODO: check for static here
894 //-----------------------------------------------------------------------------
895 // name: type_engine_scan1_op_chuck()
897 //-----------------------------------------------------------------------------
898 t_CKBOOL
type_engine_scan1_op_chuck( Chuck_Env
* env
, a_Exp lhs
, a_Exp rhs
,
899 a_Exp_Binary binary
)
907 //-----------------------------------------------------------------------------
908 // name: type_engine_scan1_op_unchuck()
910 //-----------------------------------------------------------------------------
911 t_CKBOOL
type_engine_scan1_op_unchuck( Chuck_Env
* env
, a_Exp lhs
, a_Exp rhs
)
919 //-----------------------------------------------------------------------------
920 // name: type_engine_scan1_op_upchuck()
922 //-----------------------------------------------------------------------------
923 t_CKBOOL
type_engine_scan1_op_upchuck( Chuck_Env
* env
, a_Exp lhs
, a_Exp rhs
)
931 //-----------------------------------------------------------------------------
932 // name: type_engine_scan1_op_at_chuck()
934 //-----------------------------------------------------------------------------
935 t_CKBOOL
type_engine_scan1_op_at_chuck( Chuck_Env
* env
, a_Exp lhs
, a_Exp rhs
)
943 //-----------------------------------------------------------------------------
944 // name: type_engine_scan1_exp_unary()
946 //-----------------------------------------------------------------------------
947 t_CKBOOL
type_engine_scan1_exp_unary( Chuck_Env
* env
, a_Exp_Unary unary
)
955 //-----------------------------------------------------------------------------
956 // name: type_engine_scan1_exp_primary()
958 //-----------------------------------------------------------------------------
959 t_CKBOOL
type_engine_scan1_exp_primary( Chuck_Env
* env
, a_Exp_Primary exp
)
967 //-----------------------------------------------------------------------------
968 // name: type_engine_scan1_exp_array_lit()
970 //-----------------------------------------------------------------------------
971 t_CKBOOL
type_engine_scan1_exp_array_lit( Chuck_Env
* env
, a_Exp_Primary exp
)
973 // verify there are no errors from the parser...
974 if( !verify_array( exp
->array
) )
983 //-----------------------------------------------------------------------------
984 // name: type_engine_scan1_exp_cast()
986 //-----------------------------------------------------------------------------
987 t_CKBOOL
type_engine_scan1_exp_cast( Chuck_Env
* env
, a_Exp_Cast cast
)
990 t_CKBOOL t
= type_engine_scan1_exp( env
, cast
->exp
);
991 if( !t
) return FALSE
;
999 //-----------------------------------------------------------------------------
1000 // name: type_engine_scan1_exp_dur()
1002 //-----------------------------------------------------------------------------
1003 t_CKBOOL
type_engine_scan1_exp_dur( Chuck_Env
* env
, a_Exp_Dur dur
)
1005 // type check the two components
1006 t_CKBOOL base
= type_engine_scan1_exp( env
, dur
->base
);
1007 t_CKBOOL unit
= type_engine_scan1_exp( env
, dur
->unit
);
1009 // make sure both type check
1010 if( !base
|| !unit
) return FALSE
;
1018 //-----------------------------------------------------------------------------
1019 // name: type_engine_scan1_exp_postfix()
1021 //-----------------------------------------------------------------------------
1022 t_CKBOOL
type_engine_scan1_exp_postfix( Chuck_Env
* env
, a_Exp_Postfix postfix
)
1025 t_CKBOOL t
= type_engine_scan1_exp( env
, postfix
->exp
);
1026 if( !t
) return FALSE
;
1029 // TODO: figure out ++/--
1030 switch( postfix
->op
)
1032 case ae_op_plusplus
:
1033 case ae_op_minusminus
:
1035 if( postfix
->exp
->s_meta
!= ae_meta_var
)
1037 EM_error2( postfix
->exp
->linepos
,
1038 "postfix operator '%s' cannot be used on non-mutable data-type...",
1039 op2str( postfix
->op
) );
1043 // TODO: mark somewhere we need to post increment
1050 EM_error2( postfix
->linepos
,
1051 "internal compiler error (pre-scan): unrecognized postfix '%i'", postfix
->op
);
1061 //-----------------------------------------------------------------------------
1062 // name: type_engine_scan1_exp_if()
1064 //-----------------------------------------------------------------------------
1065 t_CKBOOL
type_engine_scan1_exp_if( Chuck_Env
* env
, a_Exp_If exp_if
)
1067 // check the components
1068 t_CKBOOL cond
= type_engine_scan1_exp( env
, exp_if
->cond
);
1069 t_CKBOOL if_exp
= type_engine_scan1_exp( env
, exp_if
->if_exp
);
1070 t_CKBOOL else_exp
= type_engine_scan1_exp( env
, exp_if
->else_exp
);
1072 // make sure everything good
1073 if( !cond
|| !if_exp
|| !else_exp
) return FALSE
;
1081 //-----------------------------------------------------------------------------
1082 // name: type_engine_scan1_array_subscripts( )
1084 //-----------------------------------------------------------------------------
1085 t_CKBOOL
type_engine_scan1_array_subscripts( Chuck_Env
* env
, a_Exp exp_list
)
1093 //-----------------------------------------------------------------------------
1094 // name: type_engine_scan1_exp_decl( )
1096 //-----------------------------------------------------------------------------
1097 t_CKBOOL
type_engine_scan1_exp_decl( Chuck_Env
* env
, a_Exp_Decl decl
)
1099 a_Var_Decl_List list
= decl
->var_decl_list
;
1100 a_Var_Decl var_decl
= NULL
;
1103 // TODO: handle T a, b, c...
1104 // TODO: do we climb?
1105 t_CKTYPE t
= type_engine_find_type( env
, decl
->type
->xid
);
1106 // if not found, try to resolve
1110 EM_error2( decl
->linepos
, "... in declaration ..." );
1114 // loop through the variables
1115 while( list
!= NULL
)
1118 var_decl
= list
->var_decl
;
1120 decl
->num_var_decls
++;
1123 if( var_decl
->array
!= NULL
)
1125 // verify there are no errors from the parser...
1126 if( !verify_array( var_decl
->array
) )
1129 // may be partial and empty []
1130 if( var_decl
->array
->exp_list
)
1132 // type check the exp
1133 if( !type_engine_scan1_exp( env
, var_decl
->array
->exp_list
) )
1135 // make sure types are of int
1136 if( !type_engine_scan1_array_subscripts( env
, var_decl
->array
->exp_list
) )
1141 // the next var decl
1145 // remember : decl->ck_type = t;
1146 SAFE_REF_ASSIGN( decl
->ck_type
, t
);
1154 //-----------------------------------------------------------------------------
1155 // name: type_engine_scan1_exp_func_call()
1157 //-----------------------------------------------------------------------------
1158 t_CKBOOL
type_engine_scan1_exp_func_call( Chuck_Env
* env
, a_Exp exp_func
, a_Exp args
,
1159 t_CKFUNC
& ck_func
, int linepos
)
1161 // Chuck_Func * func = NULL;
1162 // Chuck_Func * up = NULL;
1164 // type check the func
1165 t_CKBOOL f
= type_engine_scan1_exp( env
, exp_func
);
1166 if( !f
) return FALSE
;
1168 // check the arguments
1171 t_CKBOOL a
= type_engine_scan1_exp( env
, args
);
1172 if( !a
) return FALSE
;
1181 //-----------------------------------------------------------------------------
1182 // name: type_engine_scan1_exp_func_call()
1184 //-----------------------------------------------------------------------------
1185 t_CKBOOL
type_engine_scan1_exp_func_call( Chuck_Env
* env
, a_Exp_Func_Call func_call
)
1188 return type_engine_scan1_exp_func_call( env
, func_call
->func
, func_call
->args
,
1189 func_call
->ck_func
, func_call
->linepos
);
1195 //-----------------------------------------------------------------------------
1196 // name: type_engine_scan1_exp_dot_member()
1198 //-----------------------------------------------------------------------------
1199 t_CKBOOL
type_engine_scan1_exp_dot_member( Chuck_Env
* env
, a_Exp_Dot_Member member
)
1201 // type check the base
1202 t_CKBOOL base
= type_engine_scan1_exp( env
, member
->base
);
1203 if( !base
) return FALSE
;
1211 //-----------------------------------------------------------------------------
1212 // name: type_engine_scan1_exp_array()
1214 //-----------------------------------------------------------------------------
1215 t_CKBOOL
type_engine_scan1_exp_array( Chuck_Env
* env
, a_Exp_Array array
)
1217 // verify there are no errors from the parser...
1218 if( !verify_array( array
->indices
) )
1221 // type check the base
1222 t_CKBOOL base
= type_engine_scan1_exp( env
, array
->base
);
1223 if( !base
) return FALSE
;
1225 // type check the index
1226 t_CKBOOL index
= type_engine_scan1_exp( env
, array
->indices
->exp_list
);
1227 if( !index
) return FALSE
;
1229 // cycle through each exp
1230 // a_Exp e = array->indices->exp_list;
1231 // count the dimension
1232 // t_CKUINT depth = 0;
1240 //-----------------------------------------------------------------------------
1241 // name: type_engine_scan1_class_def()
1243 //-----------------------------------------------------------------------------
1244 t_CKBOOL
type_engine_scan1_class_def( Chuck_Env
* env
, a_Class_Def class_def
)
1247 t_CKBOOL ret
= TRUE
;
1249 a_Class_Body body
= class_def
->body
;
1251 Chuck_Type
* the_class
= class_def
->type
;
1253 // set the new type as current
1254 env
->nspc_stack
.push_back( env
->curr
);
1255 env
->curr
= the_class
->info
;
1256 // push the class def
1257 env
->class_stack
.push_back( env
->class_def
);
1258 env
->class_def
= the_class
;
1259 // reset the nest list
1260 env
->class_scope
= 0;
1262 // type check the body
1263 while( body
&& ret
)
1265 // check the section
1266 switch( body
->section
->s_type
)
1268 case ae_section_stmt
:
1269 // do the statements
1270 ret
= type_engine_scan1_stmt_list( env
, body
->section
->stmt_list
);
1273 case ae_section_func
:
1275 ret
= type_engine_scan1_func_def( env
, body
->section
->func_def
);
1278 case ae_section_class
:
1280 ret
= type_engine_scan1_class_def( env
, body
->section
->class_def
);
1284 // move to the next section
1289 env
->class_def
= env
->class_stack
.back();
1290 env
->class_stack
.pop_back();
1291 // pop the namesapce
1292 env
->curr
= env
->nspc_stack
.back();
1293 env
->nspc_stack
.pop_back();
1301 //-----------------------------------------------------------------------------
1302 // name: type_engine_scan1_func_def()
1304 //-----------------------------------------------------------------------------
1305 t_CKBOOL
type_engine_scan1_func_def( Chuck_Env
* env
, a_Func_Def f
)
1307 a_Arg_List arg_list
= NULL
;
1309 // t_CKBOOL has_code = FALSE;
1310 // Chuck_Value * v = NULL;
1312 // if not imported, then check to make sure no reserved word conflict
1313 // if( f->s_type != ae_func_builtin ) // TODO: fix this
1315 // check if reserved
1316 if( type_engine_check_reserved( env
, f
->name
, f
->linepos
) )
1318 EM_error2( f
->linepos
, "...in function definition '%s'",
1323 // look up the return type
1324 f
->ret_type
= type_engine_find_type( env
, f
->type_decl
->xid
);
1328 // TODO: try to resolve
1329 EM_error2( f
->linepos
, "... in return type of function '%s' ...", S_name(f
->name
) );
1333 if( f
->type_decl
->array
!= NULL
)
1335 // verify there are no errors from the parser...
1336 if( !verify_array( f
->type_decl
->array
) )
1339 Chuck_Type
* t
= NULL
;
1340 Chuck_Type
* t2
= f
->ret_type
;
1341 // should be partial and empty []
1342 if( f
->type_decl
->array
->exp_list
)
1344 EM_error2( f
->type_decl
->array
->linepos
, "function '%s':", S_name(f
->name
) );
1345 EM_error2( f
->type_decl
->array
->linepos
, "return array type must be defined with empty []'s" );
1349 // create the new array type
1352 &t_array
, // the array base class, usually &t_array
1353 f
->type_decl
->array
->depth
, // the depth of the new type
1354 t2
, // the 'array_type'
1355 env
->curr
// the owner namespace
1360 f
->type_decl
->ref
= TRUE
;
1361 // replace type : f->ret_type = t
1362 SAFE_REF_ASSIGN( f
->ret_type
, t
);
1365 // look up types for the function arguments
1366 arg_list
= f
->arg_list
;
1369 // loop over arguments
1372 // look up in type table
1373 arg_list
->type
= type_engine_find_type( env
, arg_list
->type_decl
->xid
);
1374 // if not there, try to resolve
1375 if( !arg_list
->type
)
1377 // TODO: try to resolve
1378 // EM_error2( arg_list->linepos, "in function '%s':", S_name(f->name) );
1379 EM_error2( arg_list
->linepos
,
1380 "... in argument %i '%s' of function '%s(.)' ...",
1381 count
, S_name(arg_list
->var_decl
->xid
), S_name(f
->name
) );
1388 arg_list
= arg_list
->next
;
1391 // scan the code for types that need resolution
1392 assert( f
->code
== NULL
|| f
->code
->s_type
== ae_stmt_code
);
1393 if( f
->code
&& !type_engine_scan1_code_segment( env
, &f
->code
->stmt_code
, FALSE
) )
1395 EM_error2( 0, "...in function '%s'", S_name(f
->name
) );
1409 //-----------------------------------------------------------------------------
1410 // name: type_engine_scan2_prog()
1411 // desc: data in env should be ready
1412 //-----------------------------------------------------------------------------
1413 t_CKBOOL
type_engine_scan2_prog( Chuck_Env
* env
, a_Program prog
,
1414 te_HowMuch how_much
)
1416 t_CKBOOL ret
= TRUE
;
1422 EM_log( CK_LOG_FINER
, "(pass 2) type verification scan '%s'...",
1423 env
->context
->filename
.c_str() );
1427 EM_log( CK_LOG_FINER
, "target: %s", howmuch2str( how_much
) );
1429 // go through each of the program sections
1430 while( prog
&& ret
)
1432 switch( prog
->section
->s_type
)
1434 case ae_section_stmt
:
1435 // if classes only, then skip
1436 if( how_much
== te_do_classes_only
) break;
1437 // scan the statements
1438 ret
= type_engine_scan2_stmt_list( env
, prog
->section
->stmt_list
);
1441 case ae_section_func
:
1442 // if classes only, then skip
1443 if( how_much
== te_do_classes_only
) break;
1444 // scan the function definition
1445 ret
= type_engine_scan2_func_def( env
, prog
->section
->func_def
);
1448 case ae_section_class
:
1449 // if no classes, then skip
1450 if( how_much
== te_do_no_classes
) break;
1451 // scan the class definition
1452 ret
= type_engine_scan2_class_def( env
, prog
->section
->class_def
);
1456 EM_error2( prog
->linepos
,
1457 "internal error: unrecognized program section in type checker pre-scan..." );
1474 //-----------------------------------------------------------------------------
1475 // name: type_engine_scan2_stmt_list()
1477 //-----------------------------------------------------------------------------
1478 t_CKBOOL
type_engine_scan2_stmt_list( Chuck_Env
* env
, a_Stmt_List list
)
1480 // type check the stmt_list
1483 // the current statement
1484 if( !type_engine_scan2_stmt( env
, list
->stmt
) )
1487 // advance to the next statement
1497 //-----------------------------------------------------------------------------
1498 // name: type_engine_scan2_stmt(()
1500 //-----------------------------------------------------------------------------
1501 t_CKBOOL
type_engine_scan2_stmt( Chuck_Env
* env
, a_Stmt stmt
)
1503 t_CKBOOL ret
= FALSE
;
1509 switch( stmt
->s_type
)
1512 // count scope to help determine class member
1514 env
->curr
->value
.push();
1515 ret
= type_engine_scan2_if( env
, &stmt
->stmt_if
);
1516 env
->curr
->value
.pop();
1522 env
->curr
->value
.push();
1523 ret
= type_engine_scan2_for( env
, &stmt
->stmt_for
);
1524 env
->curr
->value
.pop();
1530 env
->curr
->value
.push();
1531 ret
= type_engine_scan2_while( env
, &stmt
->stmt_while
);
1532 env
->curr
->value
.pop();
1538 env
->curr
->value
.push();
1539 ret
= type_engine_scan2_until( env
, &stmt
->stmt_until
);
1540 env
->curr
->value
.pop();
1546 env
->curr
->value
.push();
1547 ret
= type_engine_scan2_loop( env
, &stmt
->stmt_loop
);
1548 env
->curr
->value
.pop();
1553 ret
= type_engine_scan2_exp( env
, stmt
->stmt_exp
);
1556 case ae_stmt_return
:
1557 ret
= type_engine_scan2_return( env
, &stmt
->stmt_return
);
1562 ret
= type_engine_scan2_code_segment( env
, &stmt
->stmt_code
);
1567 ret
= type_engine_scan2_break( env
, &stmt
->stmt_break
);
1570 case ae_stmt_continue
:
1571 ret
= type_engine_scan2_continue( env
, &stmt
->stmt_continue
);
1574 case ae_stmt_switch
:
1576 ret
= type_engine_scan2_switch( env
, &stmt
->stmt_switch
);
1581 // ret = type_engine_scan2_case( env, &stmt->stmt_case );
1584 case ae_stmt_gotolabel
:
1585 // ret = type_engine_scan2_gotolabel( env, &stmt->goto_label );
1589 EM_error2( stmt
->linepos
,
1590 "internal compiler error (pre-scan) - no stmt type '%i'!", stmt
->s_type
);
1601 //-----------------------------------------------------------------------------
1602 // name: type_engine_scan2_if()
1604 //-----------------------------------------------------------------------------
1605 t_CKBOOL
type_engine_scan2_if( Chuck_Env
* env
, a_Stmt_If stmt
)
1607 // check the conditional
1608 if( !type_engine_scan2_exp( env
, stmt
->cond
) )
1611 // TODO: ensure that conditional has valid type
1614 if( !type_engine_scan2_stmt( env
, stmt
->if_body
) )
1617 // check else, if there is one
1618 if( stmt
->else_body
)
1619 if( !type_engine_scan2_stmt( env
, stmt
->else_body
) )
1628 //-----------------------------------------------------------------------------
1629 // name: type_engine_scan2_for()
1631 //-----------------------------------------------------------------------------
1632 t_CKBOOL
type_engine_scan2_for( Chuck_Env
* env
, a_Stmt_For stmt
)
1634 // check the initial
1635 if( !type_engine_scan2_stmt( env
, stmt
->c1
) )
1638 // check the conditional
1639 if( !type_engine_scan2_stmt( env
, stmt
->c2
) )
1642 // TODO: same as if - check conditional type valid
1645 if( stmt
->c3
&& !type_engine_scan2_exp( env
, stmt
->c3
) )
1649 if( !type_engine_scan2_stmt( env
, stmt
->body
) )
1658 //-----------------------------------------------------------------------------
1659 // name: type_engine_scan2_while()
1661 //-----------------------------------------------------------------------------
1662 t_CKBOOL
type_engine_scan2_while( Chuck_Env
* env
, a_Stmt_While stmt
)
1664 // check the conditional
1665 if( !type_engine_scan2_exp( env
, stmt
->cond
) )
1668 // TODO: same as if - ensure the type in conditional is valid
1671 if( !type_engine_scan2_stmt( env
, stmt
->body
) )
1680 //-----------------------------------------------------------------------------
1681 // name: type_engine_scan2_until()
1683 //-----------------------------------------------------------------------------
1684 t_CKBOOL
type_engine_scan2_until( Chuck_Env
* env
, a_Stmt_Until stmt
)
1686 // check the conditional
1687 if( !type_engine_scan2_exp( env
, stmt
->cond
) )
1690 // TODO: same as if - ensure the type in conditional is valid
1693 if( !type_engine_scan2_stmt( env
, stmt
->body
) )
1702 //-----------------------------------------------------------------------------
1703 // name: type_engine_scan2_loop()
1705 //-----------------------------------------------------------------------------
1706 t_CKBOOL
type_engine_scan2_loop( Chuck_Env
* env
, a_Stmt_Loop stmt
)
1708 // check the conditional
1709 if( !type_engine_scan2_exp( env
, stmt
->cond
) )
1712 // TODO: same as if - ensure the type in conditional is valid
1715 if( !type_engine_scan2_stmt( env
, stmt
->body
) )
1724 //-----------------------------------------------------------------------------
1725 // name: type_engine_scan2_switch()
1727 //-----------------------------------------------------------------------------
1728 t_CKBOOL
type_engine_scan2_switch( Chuck_Env
* env
, a_Stmt_Switch stmt
)
1730 // TODO: implement this
1731 EM_error2( stmt
->linepos
, "switch not implemented..." );
1739 //-----------------------------------------------------------------------------
1740 // name: type_engine_scan2_break()
1742 //-----------------------------------------------------------------------------
1743 t_CKBOOL
type_engine_scan2_break( Chuck_Env
* env
, a_Stmt_Break br
)
1751 //-----------------------------------------------------------------------------
1752 // name: type_engine_scan2_continue()
1754 //-----------------------------------------------------------------------------
1755 t_CKBOOL
type_engine_scan2_continue( Chuck_Env
* env
, a_Stmt_Continue cont
)
1763 //-----------------------------------------------------------------------------
1764 // name: type_engine_scan2_return()
1766 //-----------------------------------------------------------------------------
1767 t_CKBOOL
type_engine_scan2_return( Chuck_Env
* env
, a_Stmt_Return stmt
)
1769 t_CKBOOL ret
= FALSE
;
1771 // check the type of the return
1773 ret
= type_engine_scan2_exp( env
, stmt
->val
);
1783 //-----------------------------------------------------------------------------
1784 // name: type_engine_scan2_code_segment()
1786 //-----------------------------------------------------------------------------
1787 t_CKBOOL
type_engine_scan2_code_segment( Chuck_Env
* env
, a_Stmt_Code stmt
,
1793 if( push
) env
->curr
->value
.push(); // env->context->nspc.value.push();
1795 t_CKBOOL t
= type_engine_scan2_stmt_list( env
, stmt
->stmt_list
);
1797 if( push
) env
->curr
->value
.pop(); // env->context->nspc.value.pop();
1807 //-----------------------------------------------------------------------------
1808 // name: type_engine_scan2_exp()
1810 //-----------------------------------------------------------------------------
1811 t_CKBOOL
type_engine_scan2_exp( Chuck_Env
* env
, a_Exp exp
)
1814 t_CKBOOL ret
= TRUE
;
1816 // loop through parallel expressions
1819 // examine the syntax
1820 switch( curr
->s_type
)
1823 ret
= type_engine_scan2_exp_binary( env
, &curr
->binary
);
1827 ret
= type_engine_scan2_exp_unary( env
, &curr
->unary
);
1831 ret
= type_engine_scan2_exp_cast( env
, &curr
->cast
);
1834 case ae_exp_postfix
:
1835 ret
= type_engine_scan2_exp_postfix( env
, &curr
->postfix
);
1839 ret
= type_engine_scan2_exp_dur( env
, &curr
->dur
);
1842 case ae_exp_primary
:
1843 ret
= type_engine_scan2_exp_primary( env
, &curr
->primary
);
1847 ret
= type_engine_scan2_exp_array( env
, &curr
->array
);
1850 case ae_exp_func_call
:
1851 ret
= type_engine_scan2_exp_func_call( env
, &curr
->func_call
);
1854 case ae_exp_dot_member
:
1855 ret
= type_engine_scan2_exp_dot_member( env
, &curr
->dot_member
);
1859 ret
= type_engine_scan2_exp_if( env
, &curr
->exp_if
);
1863 ret
= type_engine_scan2_exp_decl( env
, &curr
->decl
);
1867 EM_error2( curr
->linepos
,
1868 "internal compiler error - no expression type '%i'...",
1877 // advance to next expression
1888 //-----------------------------------------------------------------------------
1889 // name: type_engine_scan2_exp_binary()
1891 //-----------------------------------------------------------------------------
1892 t_CKBOOL
type_engine_scan2_exp_binary( Chuck_Env
* env
, a_Exp_Binary binary
)
1894 a_Exp cl
= binary
->lhs
, cr
= binary
->rhs
;
1896 // type check the lhs and rhs
1897 t_CKBOOL left
= type_engine_scan2_exp( env
, cl
);
1898 t_CKBOOL right
= type_engine_scan2_exp( env
, cr
);
1900 // if either fails, then return FALSE
1901 if( !left
|| !right
)
1907 // type check the pair
1908 if( !type_engine_scan2_op( env
, binary
->op
, cl
, cr
, binary
) )
1920 //-----------------------------------------------------------------------------
1921 // name: type_engine_scan2_op()
1923 //-----------------------------------------------------------------------------
1924 t_CKBOOL
type_engine_scan2_op( Chuck_Env
* env
, ae_Operator op
, a_Exp lhs
, a_Exp rhs
,
1925 a_Exp_Binary binary
)
1927 // TODO: check for static here
1935 //-----------------------------------------------------------------------------
1936 // name: type_engine_scan2_op_chuck()
1938 //-----------------------------------------------------------------------------
1939 t_CKBOOL
type_engine_scan2_op_chuck( Chuck_Env
* env
, a_Exp lhs
, a_Exp rhs
,
1940 a_Exp_Binary binary
)
1948 //-----------------------------------------------------------------------------
1949 // name: type_engine_scan2_op_unchuck()
1951 //-----------------------------------------------------------------------------
1952 t_CKBOOL
type_engine_scan2_op_unchuck( Chuck_Env
* env
, a_Exp lhs
, a_Exp rhs
)
1960 //-----------------------------------------------------------------------------
1961 // name: type_engine_scan2_op_upchuck()
1963 //-----------------------------------------------------------------------------
1964 t_CKBOOL
type_engine_scan2_op_upchuck( Chuck_Env
* env
, a_Exp lhs
, a_Exp rhs
)
1972 //-----------------------------------------------------------------------------
1973 // name: type_engine_scan2_op_at_chuck()
1975 //-----------------------------------------------------------------------------
1976 t_CKBOOL
type_engine_scan2_op_at_chuck( Chuck_Env
* env
, a_Exp lhs
, a_Exp rhs
)
1984 //-----------------------------------------------------------------------------
1985 // name: type_engine_scan2_exp_unary()
1987 //-----------------------------------------------------------------------------
1988 t_CKBOOL
type_engine_scan2_exp_unary( Chuck_Env
* env
, a_Exp_Unary unary
)
1996 //-----------------------------------------------------------------------------
1997 // name: type_engine_scan2_exp_primary()
1999 //-----------------------------------------------------------------------------
2000 t_CKBOOL
type_engine_scan2_exp_primary( Chuck_Env
* env
, a_Exp_Primary exp
)
2008 //-----------------------------------------------------------------------------
2009 // name: type_engine_scan2_exp_array_lit()
2011 //-----------------------------------------------------------------------------
2012 t_CKBOOL
type_engine_scan2_exp_array_lit( Chuck_Env
* env
, a_Exp_Primary exp
)
2014 // verify there are no errors from the parser...
2015 if( !verify_array( exp
->array
) )
2024 //-----------------------------------------------------------------------------
2025 // name: type_engine_scan2_exp_cast()
2027 //-----------------------------------------------------------------------------
2028 t_CKBOOL
type_engine_scan2_exp_cast( Chuck_Env
* env
, a_Exp_Cast cast
)
2031 t_CKBOOL t
= type_engine_scan2_exp( env
, cast
->exp
);
2032 if( !t
) return FALSE
;
2040 //-----------------------------------------------------------------------------
2041 // name: type_engine_scan2_exp_dur()
2043 //-----------------------------------------------------------------------------
2044 t_CKBOOL
type_engine_scan2_exp_dur( Chuck_Env
* env
, a_Exp_Dur dur
)
2046 // type check the two components
2047 t_CKBOOL base
= type_engine_scan2_exp( env
, dur
->base
);
2048 t_CKBOOL unit
= type_engine_scan2_exp( env
, dur
->unit
);
2050 // make sure both type check
2051 if( !base
|| !unit
) return FALSE
;
2059 //-----------------------------------------------------------------------------
2060 // name: type_engine_scan2_exp_postfix()
2062 //-----------------------------------------------------------------------------
2063 t_CKBOOL
type_engine_scan2_exp_postfix( Chuck_Env
* env
, a_Exp_Postfix postfix
)
2066 t_CKBOOL t
= type_engine_scan2_exp( env
, postfix
->exp
);
2067 if( !t
) return FALSE
;
2070 // TODO: figure out ++/--
2071 switch( postfix
->op
)
2073 case ae_op_plusplus
:
2074 case ae_op_minusminus
:
2076 if( postfix
->exp
->s_meta
!= ae_meta_var
)
2078 EM_error2( postfix
->exp
->linepos
,
2079 "postfix operator '%s' cannot be used on non-mutable data-type...",
2080 op2str( postfix
->op
) );
2084 // TODO: mark somewhere we need to post increment
2091 EM_error2( postfix
->linepos
,
2092 "internal compiler error (pre-scan): unrecognized postfix '%i'", postfix
->op
);
2102 //-----------------------------------------------------------------------------
2103 // name: type_engine_scan2_exp_if()
2105 //-----------------------------------------------------------------------------
2106 t_CKBOOL
type_engine_scan2_exp_if( Chuck_Env
* env
, a_Exp_If exp_if
)
2108 // check the components
2109 t_CKBOOL cond
= type_engine_scan2_exp( env
, exp_if
->cond
);
2110 t_CKBOOL if_exp
= type_engine_scan2_exp( env
, exp_if
->if_exp
);
2111 t_CKBOOL else_exp
= type_engine_scan2_exp( env
, exp_if
->else_exp
);
2113 // make sure everything good
2114 if( !cond
|| !if_exp
|| !else_exp
) return FALSE
;
2122 //-----------------------------------------------------------------------------
2123 // name: type_engine_scan2_array_subscripts( )
2125 //-----------------------------------------------------------------------------
2126 t_CKBOOL
type_engine_scan2_array_subscripts( Chuck_Env
* env
, a_Exp exp_list
)
2134 //-----------------------------------------------------------------------------
2135 // name: type_engine_scan2_exp_decl( )
2137 //-----------------------------------------------------------------------------
2138 t_CKBOOL
type_engine_scan2_exp_decl( Chuck_Env
* env
, a_Exp_Decl decl
)
2140 a_Var_Decl_List list
= decl
->var_decl_list
;
2141 a_Var_Decl var_decl
= NULL
;
2142 Chuck_Type
* type
= NULL
;
2143 Chuck_Value
* value
= NULL
;
2144 t_CKBOOL do_alloc
= TRUE
;
2146 // retrieve the type
2147 type
= decl
->ck_type
;
2148 // make sure it's not NULL
2149 assert( type
!= NULL
);
2151 // check to see type is not void
2152 if( type
->size
== 0 )
2154 EM_error( decl
->linepos
,
2155 "cannot declare variables of size '0' (i.e. 'void')..." );
2160 do_alloc
= !decl
->type
->ref
;
2162 // make sure complete
2163 if( /*!t->is_complete &&*/ do_alloc
)
2165 // check to see if class inside itself
2166 if( env
->class_def
&& equals( type
, env
->class_def
) && env
->class_scope
== 0 )
2168 EM_error2( decl
->linepos
,
2169 "...(note: object of type '%s' declared inside itself)",
2176 if( (isprim( type
) || isa( type
, &t_string
)) && decl
->type
->ref
) // TODO: string
2178 EM_error2( decl
->linepos
,
2179 "cannot declare references (@) of primitive type '%s'...",
2181 EM_error2( decl
->linepos
,
2182 "...(primitive types: 'int', 'float', 'time', 'dur')" );
2186 // loop through the variables
2187 while( list
!= NULL
)
2190 var_decl
= list
->var_decl
;
2192 // check if reserved
2193 if( type_engine_check_reserved( env
, var_decl
->xid
, var_decl
->linepos
) )
2195 EM_error2( var_decl
->linepos
,
2196 "...in variable declaration", S_name(var_decl
->xid
) );
2200 // check if locally defined
2201 if( env
->curr
->lookup_value( var_decl
->xid
, FALSE
) )
2203 EM_error2( var_decl
->linepos
,
2204 "'%s' has already been defined in the same scope...",
2205 S_name(var_decl
->xid
) );
2210 if( var_decl
->array
!= NULL
)
2212 // verify there are no errors from the parser...
2213 if( !verify_array( var_decl
->array
) )
2216 Chuck_Type
* t2
= type
;
2217 // may be partial and empty []
2218 if( var_decl
->array
->exp_list
)
2221 if( !type_engine_scan2_exp( env
, var_decl
->array
->exp_list
) )
2223 // make sure types are of int
2224 if( !type_engine_scan2_array_subscripts( env
, var_decl
->array
->exp_list
) )
2228 // create the new array type
2229 type
= new_array_type(
2231 &t_array
, // the array base class, usually &t_array
2232 var_decl
->array
->depth
, // the depth of the new type
2233 t2
, // the 'array_type'
2234 env
->curr
// the owner namespace
2238 if( !var_decl
->array
->exp_list
)
2239 decl
->type
->ref
= TRUE
;
2241 // set reference : decl->ck_type = type;
2242 SAFE_REF_ASSIGN( decl
->ck_type
, type
);
2245 // enter into value binding
2246 env
->curr
->value
.add( var_decl
->xid
,
2247 value
= env
->context
->new_Chuck_Value( type
, S_name(var_decl
->xid
) ) );
2249 // remember the owner
2250 value
->owner
= env
->curr
;
2251 value
->owner_class
= env
->func
? NULL
: env
->class_def
;
2252 value
->is_member
= ( env
->class_def
!= NULL
&&
2253 env
->class_scope
== 0 &&
2254 env
->func
== NULL
&& !decl
->is_static
);
2255 value
->is_context_global
= ( env
->class_def
== NULL
&& env
->func
== NULL
);
2256 value
->addr
= var_decl
->addr
;
2257 // flag it until the decl is checked
2258 value
->is_decl_checked
= FALSE
;
2260 // remember the value
2261 var_decl
->value
= value
;
2263 // the next var decl
2273 //-----------------------------------------------------------------------------
2274 // name: type_engine_scan2_exp_func_call()
2276 //-----------------------------------------------------------------------------
2277 t_CKBOOL
type_engine_scan2_exp_func_call( Chuck_Env
* env
, a_Exp exp_func
, a_Exp args
,
2278 t_CKFUNC
& ck_func
, int linepos
)
2280 // Chuck_Func * func = NULL;
2281 // Chuck_Func * up = NULL;
2283 // type check the func
2284 t_CKBOOL f
= type_engine_scan2_exp( env
, exp_func
);
2285 if( !f
) return FALSE
;
2287 // check the arguments
2290 t_CKBOOL a
= type_engine_scan2_exp( env
, args
);
2291 if( !a
) return FALSE
;
2300 //-----------------------------------------------------------------------------
2301 // name: type_engine_scan2_exp_func_call()
2303 //-----------------------------------------------------------------------------
2304 t_CKBOOL
type_engine_scan2_exp_func_call( Chuck_Env
* env
, a_Exp_Func_Call func_call
)
2307 return type_engine_scan2_exp_func_call( env
, func_call
->func
, func_call
->args
,
2308 func_call
->ck_func
, func_call
->linepos
);
2314 //-----------------------------------------------------------------------------
2315 // name: type_engine_scan2_exp_dot_member()
2317 //-----------------------------------------------------------------------------
2318 t_CKBOOL
type_engine_scan2_exp_dot_member( Chuck_Env
* env
, a_Exp_Dot_Member member
)
2320 // type check the base
2321 t_CKBOOL base
= type_engine_scan2_exp( env
, member
->base
);
2322 if( !base
) return FALSE
;
2330 //-----------------------------------------------------------------------------
2331 // name: type_engine_scan2_exp_array()
2333 //-----------------------------------------------------------------------------
2334 t_CKBOOL
type_engine_scan2_exp_array( Chuck_Env
* env
, a_Exp_Array array
)
2336 // verify there are no errors from the parser...
2337 if( !verify_array( array
->indices
) )
2340 // type check the base
2341 t_CKBOOL base
= type_engine_scan2_exp( env
, array
->base
);
2342 if( !base
) return FALSE
;
2344 // type check the index
2345 t_CKBOOL index
= type_engine_scan2_exp( env
, array
->indices
->exp_list
);
2346 if( !index
) return FALSE
;
2348 // cycle through each exp
2349 // a_Exp e = array->indices->exp_list;
2350 // count the dimension
2351 // t_CKUINT depth = 0;
2359 //-----------------------------------------------------------------------------
2360 // name: type_engine_scan2_class_def()
2362 //-----------------------------------------------------------------------------
2363 t_CKBOOL
type_engine_scan2_class_def( Chuck_Env
* env
, a_Class_Def class_def
)
2366 t_CKBOOL ret
= TRUE
;
2368 a_Class_Body body
= class_def
->body
;
2370 Chuck_Type
* the_class
= class_def
->type
;
2372 assert( the_class
!= NULL
);
2374 // set the new type as current
2375 env
->nspc_stack
.push_back( env
->curr
);
2376 env
->curr
= the_class
->info
;
2377 // push the class def
2378 env
->class_stack
.push_back( env
->class_def
);
2379 env
->class_def
= the_class
;
2380 // reset the nest list
2381 env
->class_scope
= 0;
2383 // type check the body
2384 while( body
&& ret
)
2386 // check the section
2387 switch( body
->section
->s_type
)
2389 case ae_section_stmt
:
2390 // already flagged as having a constructor or not
2391 ret
= type_engine_scan2_stmt_list( env
, body
->section
->stmt_list
);
2394 case ae_section_func
:
2396 ret
= type_engine_scan2_func_def( env
, body
->section
->func_def
);
2399 case ae_section_class
:
2401 ret
= type_engine_scan2_class_def( env
, body
->section
->class_def
);
2405 // move to the next section
2410 env
->class_def
= env
->class_stack
.back();
2411 env
->class_stack
.pop_back();
2412 // pop the namesapce
2413 env
->curr
= env
->nspc_stack
.back();
2414 env
->nspc_stack
.pop_back();
2422 //-----------------------------------------------------------------------------
2423 // name: type_engine_scan2_func_def()
2425 //-----------------------------------------------------------------------------
2426 t_CKBOOL
type_engine_scan2_func_def( Chuck_Env
* env
, a_Func_Def f
)
2428 Chuck_Type
* type
= NULL
;
2429 Chuck_Value
* value
= NULL
;
2430 Chuck_Func
* func
= NULL
;
2432 // Chuck_Type * parent = NULL;
2433 Chuck_Value
* overload
= NULL
;
2434 // Chuck_Value * override = NULL;
2435 Chuck_Value
* v
= NULL
;
2436 // Chuck_Func * parent_func = NULL;
2437 a_Arg_List arg_list
= NULL
;
2438 // t_CKBOOL parent_match = FALSE;
2439 string func_name
= S_name(f
->name
);
2440 string orig_name
= func_name
;
2441 vector
<Chuck_Value
*> values
;
2442 vector
<a_Arg_List
> symbols
;
2444 // t_CKBOOL has_code = FALSE; // use this for both user and imported
2446 // see if we are already in a function definition
2447 if( env
->func
!= NULL
)
2449 EM_error2( f
->linepos
,
2450 "nested function definitions are not (yet) allowed" );
2454 // make sure a code segment is in stmt - else we should push scope
2455 assert( !f
->code
|| f
->code
->s_type
== ae_stmt_code
);
2457 // look up the value in the current class (can shadow?)
2458 if(( overload
= env
->curr
->lookup_value( f
->name
, FALSE
) ))
2461 if( !isa( overload
->type
, &t_function
) )
2463 EM_error2( f
->linepos
,
2464 "function name '%s' is already used by another value", S_name(f
->name
) );
2470 if( !overload
->func_ref
)
2473 EM_error2( f
->linepos
,
2474 "internal error: missing function '%s'",
2475 overload
->name
.c_str() );
2484 // make the new name
2485 func_name
+= "@" + itoa( ++overload
->func_num_overloads
) + "@" + env
->curr
->name
;
2489 // make name using 0
2490 func_name
+= "@0@" + env
->curr
->name
;
2493 // make sure a code segment is in stmt - else we should push scope
2494 assert( !f
->code
|| f
->code
->s_type
== ae_stmt_code
);
2496 // make a new func object
2497 func
= env
->context
->new_Chuck_Func();
2499 func
->name
= func_name
;
2500 // reference the function definition
2502 // note whether the function is marked as member
2503 func
->is_member
= (f
->static_decl
!= ae_key_static
) &&
2504 (env
->class_def
!= NULL
);
2505 // copy the native code, for imported functions
2506 if( f
->s_type
== ae_func_builtin
)
2508 // we can emit code now
2509 func
->code
= new Chuck_VM_Code
;
2510 // whether the function needs 'this'
2511 func
->code
->need_this
= func
->is_member
;
2512 // set the function pointer
2513 func
->code
->native_func
= (t_CKUINT
)func
->def
->dl_func_ptr
;
2516 // make a new type for the function
2517 type
= env
->context
->new_Chuck_Type();
2518 type
->xid
= te_function
;
2519 type
->name
= "[function]";
2520 type
->parent
= &t_function
;
2521 type
->size
= sizeof(void *);
2524 // make new value, with potential overloaded name
2525 value
= env
->context
->new_Chuck_Value( type
, func_name
);
2527 value
->is_const
= TRUE
;
2528 // remember the owner
2529 value
->owner
= env
->curr
;
2530 value
->owner_class
= env
->class_def
;
2531 value
->is_member
= func
->is_member
;
2532 // is global context
2533 value
->is_context_global
= env
->class_def
== NULL
;
2534 // remember the func
2535 value
->func_ref
= func
; func
->add_ref(); // add reference TODO: break cycle?
2536 // remember the value
2537 func
->value_ref
= value
; value
->add_ref(); // add reference TODO: break cycle?
2540 f
->ck_func
= func
; func
->add_ref(); // add reference
2546 func
->next
= overload
->func_ref
->next
;
2547 overload
->func_ref
->next
= func
;
2551 assert( f
->ret_type
!= NULL
);
2554 if( (isprim( f
->ret_type
) /*|| isa( f->ret_type, &t_string )*/)
2555 && f
->type_decl
->ref
) // TODO: string
2557 EM_error2( f
->type_decl
->linepos
,
2558 "cannot declare references (@) of primitive type '%s'...",
2559 f
->ret_type
->c_name() );
2560 EM_error2( f
->type_decl
->linepos
,
2561 "...(primitive types: 'int', 'float', 'time', 'dur')" );
2565 // look up types for the function arguments
2566 arg_list
= f
->arg_list
;
2569 // make room for 'this'
2570 f
->stack_depth
= func
->is_member
? sizeof(void *) : 0;
2571 // loop over arguments
2574 // make sure the type is not NULL - it should have been
2575 // set in scan1_func_def()...
2576 assert( arg_list
->type
!= NULL
);
2578 // make sure it's not void
2579 if( arg_list
->type
->size
== 0 )
2581 EM_error2( arg_list
->linepos
,
2582 "cannot declare variables of size '0' (i.e. 'void')..." );
2586 // check if reserved
2587 if( type_engine_check_reserved( env
, arg_list
->var_decl
->xid
, arg_list
->linepos
) )
2589 EM_error2( arg_list
->linepos
, "in function '%s'", S_name(f
->name
) );
2593 // look up in scope: later
2594 //if( env->curr->lookup_value( arg_list->var_decl->xid, FALSE ) )
2596 // EM_error2( arg_list->linepos, "in function '%s':", S_name(f->name) );
2597 // EM_error2( arg_list->linepos, "argument %i '%s' is already defined in this scope",
2598 // count, S_name(arg_list->var_decl->xid) );
2603 if( (isprim( arg_list
->type
) /*|| isa( arg_list->type, &t_string )*/)
2604 && arg_list
->type_decl
->ref
) // TODO: string
2606 EM_error2( arg_list
->type_decl
->linepos
,
2607 "cannot declare references (@) of primitive type '%s'...",
2608 arg_list
->type
->c_name() );
2609 EM_error2( arg_list
->type_decl
->linepos
,
2610 "...(primitive types: 'int', 'float', 'time', 'dur')" );
2615 if( arg_list
->var_decl
->array
!= NULL
)
2617 // verify there are no errors from the parser...
2618 if( !verify_array( arg_list
->var_decl
->array
) )
2621 Chuck_Type
* t
= arg_list
->type
;
2622 Chuck_Type
* t2
= t
;
2623 // should be partial and empty []
2624 if( arg_list
->var_decl
->array
->exp_list
)
2626 EM_error2( arg_list
->linepos
, "in function '%s':", S_name(f
->name
) );
2627 EM_error2( arg_list
->linepos
, "argument %i '%s' must be defined with empty []'s",
2628 count
, S_name(arg_list
->var_decl
->xid
) );
2632 // create the new array type
2635 &t_array
, // the array base class, usually &t_array
2636 arg_list
->var_decl
->array
->depth
, // the depth of the new type
2637 t2
, // the 'array_type'
2638 env
->curr
// the owner namespace
2642 arg_list
->type_decl
->ref
= TRUE
;
2643 // set type : arg_list->type = t;
2644 SAFE_REF_ASSIGN( arg_list
->type
, t
);
2648 v
= env
->context
->new_Chuck_Value(
2649 arg_list
->type
, S_name(arg_list
->var_decl
->xid
) );
2650 // remember the owner
2651 v
->owner
= env
->curr
;
2652 // function args not owned
2653 v
->owner_class
= NULL
;
2654 v
->is_member
= FALSE
;
2655 // later: add as value
2656 // symbols.push_back( arg_list );
2657 // values.push_back( v );
2658 // later: env->curr->value.add( arg_list->var_decl->xid, v );
2661 v
->offset
= f
->stack_depth
;
2662 f
->stack_depth
+= arg_list
->type
->size
;
2665 arg_list
->var_decl
->value
= v
;
2670 arg_list
= arg_list
->next
;
2674 env
->curr
->value
.add( value
->name
, value
);
2675 // enter the name into the function table
2676 env
->curr
->func
.add( func
->name
, func
);
2678 // add for orig name
2681 env
->curr
->value
.add( orig_name
, value
);
2682 env
->curr
->func
.add( orig_name
, func
);
2688 // make sure returns are equal
2689 if( *(f
->ret_type
) != *(overload
->func_ref
->def
->ret_type
) )
2691 EM_error2( f
->linepos
, "function signatures differ in return type..." );
2692 EM_error2( f
->linepos
,
2693 "function '%s.%s' matches '%s.%s' but cannot overload...",
2694 env
->class_def
->c_name(), S_name(f
->name
),
2695 value
->owner_class
->c_name(), S_name(f
->name
) );
2700 // set the current function to this
2702 // push the value stack
2703 env
->curr
->value
.push();
2706 assert( f
->code
== NULL
|| f
->code
->s_type
== ae_stmt_code
);
2707 if( f
->code
&& !type_engine_scan2_code_segment( env
, &f
->code
->stmt_code
, FALSE
) )
2709 EM_error2( 0, "...in function '%s'", S_name(f
->name
) );
2713 // pop the value stack
2714 env
->curr
->value
.pop();
2715 // clear the env's function definition