History

core ejected

Ge Wang committed 9 years ago

Commit d38351c1 parent 74cf4d4158 files · +0 −196800Browse files

Unified · Split

158 files
  1. core/chuck.cpp +0 −768
  2. core/chuck.h +0 −173
  3. core/chuck.lex +0 −328
  4. core/chuck.tab.c +0 −3141
  5. core/chuck.tab.h +0 −203
  6. core/chuck.y +0 −600
  7. core/chuck_absyn.cpp +0 −972
  8. core/chuck_absyn.h +0 −406
  9. core/chuck_carrier.h +0 −94
  10. core/chuck_compile.cpp +0 −900
  11. core/chuck_compile.h +0 −138
  12. core/chuck_def.h +0 −203
  13. core/chuck_dl.cpp +0 −1151
  14. core/chuck_dl.h +0 −732
  15. core/chuck_emit.cpp +0 −5072
  16. core/chuck_emit.h +0 −176
  17. core/chuck_errmsg.cpp +0 −650
  18. core/chuck_errmsg.h +0 −177
  19. core/chuck_frame.cpp +0 −165
  20. core/chuck_frame.h +0 −103
  21. core/chuck_instr.cpp +0 −7490
  22. core/chuck_instr.h +0 −4047
  23. core/chuck_io.cpp +0 −1949
  24. core/chuck_io.h +0 −204
  25. core/chuck_lang.cpp +0 −4860
  26. core/chuck_lang.h +0 −481
  27. core/chuck_oo.cpp +0 −3285
  28. core/chuck_oo.h +0 −708
  29. core/chuck_otf.cpp +0 −747
  30. core/chuck_otf.h +0 −101
  31. core/chuck_parse.cpp +0 −230
  32. core/chuck_parse.h +0 −153
  33. core/chuck_scan.cpp +0 −2732
  34. core/chuck_scan.h +0 −71
  35. core/chuck_shell.cpp +0 −2260
  36. core/chuck_shell.h +0 −578
  37. core/chuck_stats.cpp +0 −302
  38. core/chuck_stats.h +0 −198
  39. core/chuck_symbol.cpp +0 −143
  40. core/chuck_symbol.h +0 −88
  41. core/chuck_table.cpp +0 −221
  42. core/chuck_table.h +0 −76
  43. core/chuck_type.cpp +0 −6488
  44. core/chuck_type.h +0 −970
  45. core/chuck_ugen.cpp +0 −1543
  46. core/chuck_ugen.h +0 −199
  47. core/chuck_utils.cpp +0 −77
  48. core/chuck_utils.h +0 −62
  49. core/chuck_vm.cpp +0 −2760
  50. core/chuck_vm.h +0 −755
  51. core/chuck_win32.c +0 −2632
  52. core/chuck_win32.h +0 −203
  53. core/dirent_win32.h +0 −234
  54. core/hidio_sdl.cpp +0 −1032
  55. core/hidio_sdl.h +0 −172
  56. core/lo/address.c +0 −346
  57. core/lo/blob.c +0 −64
  58. core/lo/bundle.c +0 −181
  59. core/lo/config.h +0 −200
  60. core/lo/lo.h +0 −353
  61. core/lo/lo_endian.h +0 −256
  62. core/lo/lo_errors.h +0 −45
  63. core/lo/lo_internal.h +0 −63
  64. core/lo/lo_lowlevel.h +0 −860
  65. core/lo/lo_macros.h +0 −80
  66. core/lo/lo_osc_types.h +0 −145
  67. core/lo/lo_throw.h +0 −30
  68. core/lo/lo_types.h +0 −143
  69. core/lo/lo_types_internal.h +0 −145
  70. core/lo/message.c +0 −1081
  71. core/lo/method.c +0 −35
  72. core/lo/pattern_match.c +0 −248
  73. core/lo/send.c +0 −491
  74. core/lo/server.c +0 −1400
  75. core/lo/server_thread.c +0 −188
  76. core/lo/timetag.c +0 −58
  77. core/midiio_rtmidi.cpp +0 −1010
  78. core/midiio_rtmidi.h +0 −278
  79. core/regex/LICENSE.txt +0 −29
  80. core/regex/README.txt +0 −235
  81. core/regex/config.h +0 −184
  82. core/regex/regcomp.c +0 −129
  83. core/regex/regerror.c +0 −83
  84. core/regex/regex.h +0 −38
  85. core/regex/regexec.c +0 −348
  86. core/regex/tre-ast.c +0 −226
  87. core/regex/tre-ast.h +0 −128
  88. core/regex/tre-compile.c +0 −2296
  89. core/regex/tre-compile.h +0 −27
  90. core/regex/tre-config.h +0 −52
  91. core/regex/tre-filter.c +0 −73
  92. core/regex/tre-filter.h +0 −19
  93. core/regex/tre-internal.h +0 −287
  94. core/regex/tre-match-approx.c +0 −812
  95. core/regex/tre-match-backtrack.c +0 −666
  96. core/regex/tre-match-parallel.c +0 −501
  97. core/regex/tre-match-utils.h +0 −215
  98. core/regex/tre-mem.c +0 −155
  99. core/regex/tre-mem.h +0 −66
  100. core/regex/tre-parse.c +0 −1739
  101. core/regex/tre-parse.h +0 −50
  102. core/regex/tre-stack.c +0 −125
  103. core/regex/tre-stack.h +0 −76
  104. core/regex/tre.h +0 −276
  105. core/regex/xmalloc.c +0 −351
  106. core/regex/xmalloc.h +0 −77
  107. core/rtmidi.cpp +0 −2322
  108. core/rtmidi.h +0 −362
  109. core/uana_extract.cpp +0 −1526
  110. core/uana_extract.h +0 −45
  111. core/uana_xform.cpp +0 −3762
  112. core/uana_xform.h +0 −45
  113. core/ugen_filter.cpp +0 −2694
  114. core/ugen_filter.h +0 −238
  115. core/ugen_osc.cpp +0 −1759
  116. core/ugen_osc.h +0 −112
  117. core/ugen_stk.cpp +0 −27019
  118. core/ugen_stk.h +0 −6622
  119. core/ugen_xxx.cpp +0 −4964
  120. core/ugen_xxx.h +0 −256
  121. core/ulib_machine.cpp +0 −220
  122. core/ulib_machine.h +0 −62
  123. core/ulib_math.cpp +0 −777
  124. core/ulib_math.h +0 −100
  125. core/ulib_opsc.cpp +0 −1662
  126. core/ulib_opsc.h +0 −79
  127. core/ulib_regex.cpp +0 −404
  128. core/ulib_regex.h +0 −40
  129. core/ulib_std.cpp +0 −1985
  130. core/ulib_std.h +0 −143
  131. core/util_buffers.cpp +0 −1022
  132. core/util_buffers.h +0 −698
  133. core/util_console.cpp +0 −210
  134. core/util_console.h +0 −51
  135. core/util_hid.cpp +0 −8068
  136. core/util_hid.h +0 −221
  137. core/util_math.c +0 −200
  138. core/util_math.h +0 −75
  139. core/util_network.c +0 −442
  140. core/util_network.h +0 −105
  141. core/util_opsc.cpp +0 −2540
  142. core/util_opsc.h +0 −630
  143. core/util_raw.c +0 −4784
  144. core/util_raw.h +0 −100
  145. core/util_serial.cpp +0 −248
  146. core/util_serial.h +0 −58
  147. core/util_sndfile.c +0 −34323
  148. core/util_sndfile.h +0 −2706
  149. core/util_string.cpp +0 −569
  150. core/util_string.h +0 −87
  151. core/util_thread.cpp +0 −523
  152. core/util_thread.h +0 −233
  153. core/util_xforms.c +0 −454
  154. core/util_xforms.h +0 −89
  155. src/scripts/compressSndFile.pl +0 −0
  156. src/scripts/hex2cpp.cpp +0 −0
  157. src/scripts/platform.cpp +0 −0
  158. src/scripts/raw2code.cpp +0 −0
core/chuck.cpp+0−768
@@ -1,768 +0,0 @@
1/*----------------------------------------------------------------------------
2 ChucK Concurrent, On-the-fly Audio Programming Language
3 Compiler and Virtual Machine
4
5 Copyright (c) 2003 Ge Wang and Perry R. Cook. All rights reserved.
6 http://chuck.stanford.edu/
7 http://chuck.cs.princeton.edu/
8
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.
13
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.
18
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 -----------------------------------------------------------------------------*/
24
25//-----------------------------------------------------------------------------
26// file: chuck.h
27// desc: chuck engine header; VM + compiler + state; no audio I/O
28// REFACTOR-2017
29//
30// author: Ge Wang (http://www.gewang.com/)
31// date: fall 2017
32//
33// additional authors:
34// Jack Atherton (lja@ccrma.stanford.edu)
35// Spencer Salazar (spencer@ccrma.stanford.edu)
36//-----------------------------------------------------------------------------
37#include "chuck.h"
38#include "chuck_errmsg.h"
39#include "chuck_otf.h"
40#include "ulib_machine.h"
41#include "util_string.h"
42
43
44
45
46// chuck param defaults
47#define CHUCK_PARAM_SAMPLE_RATE_DEFAULT "44100"
48#define CHUCK_PARAM_INPUT_CHANNELS_DEFAULT "2"
49#define CHUCK_PARAM_OUTPUT_CHANNELS_DEFAULT "2"
50#define CHUCK_PARAM_VM_ADAPTIVE_DEFAULT "0"
51#define CHUCK_PARAM_VM_HALT_DEFAULT "0"
52#define CHUCK_PARAM_OTF_PORT_DEFAULT "8888"
53#define CHUCK_PARAM_DUMP_INSTRUCTIONS_DEFAULT "0"
54#define CHUCK_PARAM_DEPRECATE_LEVEL_DEFAULT "1"
55#define CHUCK_PARAM_WORKING_DIRECTORY_DEFAULT ""
56#define CHUCK_PARAM_CHUGIN_DIRECTORY_DEFAULT ""
57
58
59
60// chuck statics
61// version
62const char ChucK::VERSION[] = "1.3.6.0-rc1 (numchuck)";
63t_CKUINT ChucK::o_numVMs = 0;
64
65
66
67
68//-----------------------------------------------------------------------------
69// name: version()
70// desc: get chuck version
71//-----------------------------------------------------------------------------
72const char * ChucK::version()
73{
74 return VERSION;
75}
76
77
78
79
80//-----------------------------------------------------------------------------
81// name: intSize()
82// desc: get chuck int size (in bits)
83//-----------------------------------------------------------------------------
84t_CKUINT ChucK::intSize()
85{
86 return machine_intsize();
87}
88
89
90
91
92//-----------------------------------------------------------------------------
93// name: ChucK()
94// desc: constructor
95//-----------------------------------------------------------------------------
96ChucK::ChucK()
97{
98 // instantiate the carrier!
99 m_carrier = new Chuck_Carrier();
100 // increment the numChucKs
101 o_numVMs++;
102 // initialize default params
103 initDefaultParams();
104 // did user init?
105 m_init = FALSE;
106}
107
108
109
110
111//-----------------------------------------------------------------------------
112// name: ~ChucK()
113// desc: destructor
114//-----------------------------------------------------------------------------
115ChucK::~ChucK()
116{
117 // shutdown
118 shutdown();
119 // decrement the numChucKs
120 o_numVMs--;
121}
122
123
124
125
126// REFACTOR-2017: TODO Ge: Implementation of this?
127//-----------------------------------------------------------------------------
128// name: ck_param_type
129// desc: enum for type of param (int, float, string)
130//-----------------------------------------------------------------------------
131enum ck_param_type
132{
133 ck_param_int, ck_param_float, ck_param_string
134};
135
136
137
138//-----------------------------------------------------------------------------
139// name: ck_param_types
140// desc: storage for types of param (int, float, string)
141//-----------------------------------------------------------------------------
142std::map< std::string, ck_param_type> ck_param_types;
143
144
145
146
147//-----------------------------------------------------------------------------
148// name: initDefaultParams()
149// desc: initialize default params
150//-----------------------------------------------------------------------------
151void ChucK::initDefaultParams()
152{
153 m_params[CHUCK_PARAM_SAMPLE_RATE] = CHUCK_PARAM_SAMPLE_RATE_DEFAULT;
154 m_params[CHUCK_PARAM_INPUT_CHANNELS] = CHUCK_PARAM_INPUT_CHANNELS_DEFAULT;
155 m_params[CHUCK_PARAM_OUTPUT_CHANNELS] = CHUCK_PARAM_OUTPUT_CHANNELS_DEFAULT;
156 m_params[CHUCK_PARAM_VM_ADAPTIVE] = CHUCK_PARAM_VM_ADAPTIVE_DEFAULT;
157 m_params[CHUCK_PARAM_VM_HALT] = CHUCK_PARAM_VM_HALT_DEFAULT;
158 m_params[CHUCK_PARAM_OTF_PORT] = CHUCK_PARAM_OTF_PORT_DEFAULT;
159 m_params[CHUCK_PARAM_DUMP_INSTRUCTIONS] = CHUCK_PARAM_DUMP_INSTRUCTIONS_DEFAULT;
160 m_params[CHUCK_PARAM_DEPRECATE_LEVEL] = CHUCK_PARAM_DEPRECATE_LEVEL_DEFAULT;
161 m_params[CHUCK_PARAM_WORKING_DIRECTORY] = CHUCK_PARAM_WORKING_DIRECTORY_DEFAULT;
162 m_params[CHUCK_PARAM_CHUGIN_DIRECTORY] = CHUCK_PARAM_CHUGIN_DIRECTORY_DEFAULT;
163
164 ck_param_types[CHUCK_PARAM_SAMPLE_RATE] = ck_param_int;
165 ck_param_types[CHUCK_PARAM_INPUT_CHANNELS] = ck_param_int;
166 ck_param_types[CHUCK_PARAM_OUTPUT_CHANNELS] = ck_param_int;
167 ck_param_types[CHUCK_PARAM_VM_ADAPTIVE] = ck_param_int;
168 ck_param_types[CHUCK_PARAM_VM_HALT] = ck_param_int;
169 ck_param_types[CHUCK_PARAM_OTF_PORT] = ck_param_int;
170 ck_param_types[CHUCK_PARAM_DUMP_INSTRUCTIONS] = ck_param_int;
171 ck_param_types[CHUCK_PARAM_DEPRECATE_LEVEL] = ck_param_int;
172 ck_param_types[CHUCK_PARAM_WORKING_DIRECTORY] = ck_param_string;
173 ck_param_types[CHUCK_PARAM_CHUGIN_DIRECTORY] = ck_param_string;
174}
175
176
177
178
179//-----------------------------------------------------------------------------
180// name: setParam()
181// desc: set an int param by name
182//-----------------------------------------------------------------------------
183bool ChucK::setParam( const std::string & name, t_CKINT value )
184{
185 if( m_params.count( name ) > 0 && ck_param_types[name] == ck_param_int )
186 {
187 std::ostringstream s;
188 s << value;
189 m_params[name] = s.str();
190 return TRUE;
191 }
192 else
193 {
194 return FALSE;
195 }
196}
197
198
199
200
201//-----------------------------------------------------------------------------
202// name: setParam()
203// desc: set a float param by name
204//-----------------------------------------------------------------------------
205bool ChucK::setParam( const std::string & name, t_CKFLOAT value )
206{
207 if( m_params.count( name ) > 0 && ck_param_types[name] == ck_param_float )
208 {
209 std::ostringstream s;
210 s << value;
211 m_params[name] = s.str();
212 return TRUE;
213 }
214 else
215 {
216 return FALSE;
217 }
218}
219
220
221
222
223//-----------------------------------------------------------------------------
224// name: setParam()
225// desc: set a string param by name
226//-----------------------------------------------------------------------------
227bool ChucK::setParam( const std::string & name, const std::string & value )
228{
229 if( m_params.count( name ) > 0 && ck_param_types[name] == ck_param_string )
230 {
231 m_params[name] = value;
232 return TRUE;
233 }
234 else
235 {
236 return FALSE;
237 }
238}
239
240
241
242
243//-----------------------------------------------------------------------------
244// name: getParamInt()
245// desc: get an int param
246//-----------------------------------------------------------------------------
247t_CKINT ChucK::getParamInt( const std::string & key )
248{
249 t_CKINT result = 0;
250 if( m_params.count( key ) > 0 && ck_param_types[key] == ck_param_int )
251 {
252 istringstream s( m_params[key] );
253 s >> result;
254 }
255 return result;
256}
257
258
259
260
261//-----------------------------------------------------------------------------
262// name: getParamInt()
263// desc: get a float param
264//-----------------------------------------------------------------------------
265t_CKFLOAT ChucK::getParamFloat( const std::string & key )
266{
267 t_CKFLOAT result = 0;
268 if( m_params.count( key ) > 0 && ck_param_types[key] == ck_param_float )
269 {
270 istringstream s( m_params[key] );
271 s >> result;
272 }
273 return result;
274}
275
276
277
278
279//-----------------------------------------------------------------------------
280// name: getParamString()
281// desc: get a string param
282//-----------------------------------------------------------------------------
283std::string ChucK::getParamString( const std::string & key )
284{
285 if( m_params.count( key ) > 0 && ck_param_types[key] == ck_param_string )
286 {
287 return m_params[key];
288 }
289 else
290 {
291 return "";
292 }
293}
294
295
296
297
298//-----------------------------------------------------------------------------
299// initialize ChucK (using params)
300//-----------------------------------------------------------------------------
301bool ChucK::init()
302{
303 // sanity check
304 if( m_carrier->vm != NULL )
305 {
306 CK_FPRINTF_STDERR( "[chuck]: VM already initialized...\n" );
307 return false;
308 }
309
310 // get VM params
311 t_CKUINT srate = getParamInt( CHUCK_PARAM_SAMPLE_RATE );
312 t_CKUINT outs = getParamInt( CHUCK_PARAM_OUTPUT_CHANNELS );
313 t_CKUINT ins = getParamInt( CHUCK_PARAM_INPUT_CHANNELS );
314 t_CKUINT adaptiveSize = getParamInt( CHUCK_PARAM_VM_ADAPTIVE );
315 t_CKBOOL halt = getParamInt( CHUCK_PARAM_VM_HALT ) != 0;
316
317 // get compiler params
318 t_CKBOOL dump = getParamInt( CHUCK_PARAM_DUMP_INSTRUCTIONS ) != 0;
319 t_CKBOOL auto_depend = getParamInt( CHUCK_PARAM_AUTO_DEPEND ) != 0;
320 string workingDir = getParamString( CHUCK_PARAM_WORKING_DIRECTORY );
321 string chuginDir = getParamString( CHUCK_PARAM_CHUGIN_DIRECTORY );
322 t_CKUINT deprecate = getParamInt( CHUCK_PARAM_DEPRECATE_LEVEL );
323 // TODO: chugin load option
324 // list of search pathes (added 1.3.0.0)
325 std::list<std::string> dl_search_path;
326 if( workingDir != std::string("") )
327 {
328 dl_search_path.push_back( workingDir );
329 }
330 if( chuginDir != std::string("") )
331 {
332 dl_search_path.push_back( chuginDir );
333 }
334 // list of individually named chug-ins (added 1.3.0.0)
335 std::list<std::string> named_dls;
336
337
338 // instantiate VM
339 m_carrier->vm = new Chuck_VM();
340 // reference back to carrier
341 m_carrier->vm->setCarrier( m_carrier );
342 // initialize VM
343 if( !m_carrier->vm->initialize( srate, outs, ins, adaptiveSize, halt ) )
344 {
345 CK_FPRINTF_STDERR( "[chuck]: %s\n", m_carrier->vm->last_error() );
346 goto cleanup;
347 }
348
349 // instantiate compiler
350 m_carrier->compiler = new Chuck_Compiler();
351 // reference back to carrier
352 m_carrier->compiler->setCarrier( m_carrier );
353
354 // initialize compiler
355 if( !m_carrier->compiler->initialize( dl_search_path, named_dls ) )
356 {
357 CK_FPRINTF_STDERR( "[chuck]: compiler failed to initialize...\n" );
358 goto cleanup;
359 }
360 // set dump flag
361 m_carrier->compiler->emitter->dump = dump;
362 // set auto depend flag (for type checker) | currently must be FALSE
363 m_carrier->compiler->set_auto_depend( auto_depend );
364 // set deprecation level
365 m_carrier->env->deprecate_level = deprecate;
366
367 // VM + type system integration
368 if( !m_carrier->vm->initialize_synthesis() )
369 {
370 CK_FPRINTF_STDERR( "[chuck]: %s\n", m_carrier->vm->last_error() );
371 goto cleanup;
372 }
373
374 // TODO: load chugins
375
376 // load user namespace
377 m_carrier->env->load_user_namespace();
378
379 // did user init?
380 m_init = TRUE;
381
382 return true;
383
384cleanup:
385 // shutdown, dealloc
386 shutdown();
387
388 return false;
389}
390
391
392
393
394//-----------------------------------------------------------------------------
395// shutdown ChucK
396//-----------------------------------------------------------------------------
397bool ChucK::shutdown()
398{
399 // stop VM
400 if( m_carrier != NULL && m_carrier->vm != NULL )
401 {
402 m_carrier->vm->stop();
403
404 // wait for it to stop...
405 while( m_carrier->vm->running() )
406 {
407 usleep(1000);
408 }
409 }
410
411 // free vm, compiler, friends
412 // TODO: a different way to unlock?
413 // unlock all objects to delete chout, cherr
414 Chuck_VM_Object::unlock_all();
415 SAFE_RELEASE( m_carrier->chout );
416 SAFE_RELEASE( m_carrier->cherr );
417 // relock
418 Chuck_VM_Object::lock_all();
419 SAFE_DELETE( m_carrier->vm );
420 SAFE_DELETE( m_carrier->compiler );
421 m_carrier->env = NULL;
422 m_carrier->otf_socket = NULL; // TODO: properly dealloc
423 m_carrier->otf_port = 0;
424 m_carrier->otf_thread = 0; // TODO: properly dealloc
425
426 // done
427 return true;
428}
429
430
431
432
433//-----------------------------------------------------------------------------
434// name: compileFile()
435// desc: compile a file (can be called anytime)
436//-----------------------------------------------------------------------------
437bool ChucK::compileFile( const std::string & path, const std::string & argsTogether, int count )
438{
439 // sanity check
440 if( !m_carrier->compiler )
441 {
442 // error
443 CK_FPRINTF_STDERR( "[chuck]: compileFile() invoked before initialization ...\n" );
444 return false;
445 }
446
447 string filename;
448 vector<string> args;
449 Chuck_VM_Code * code = NULL;
450 Chuck_VM_Shred * shred = NULL;
451
452 // log
453 EM_log( CK_LOG_FINE, "compiling '%s'...", filename.c_str() );
454 // push indent
455 EM_pushlog();
456
457 // append
458 string theThing = path + ":" + argsTogether;
459
460 // parse out command line arguments
461 if( !extract_args( theThing, filename, args ) )
462 {
463 // error
464 CK_FPRINTF_STDERR( "[chuck]: malformed filename with argument list...\n" );
465 CK_FPRINTF_STDERR( " --> '%s'", theThing.c_str() );
466 return false;
467 }
468
469 // construct full path to be associated with the file so me.sourceDir() works
470 // (added 1.3.0.0)
471 std::string full_path = get_full_path(filename);
472
473 // parse, type-check, and emit (full_path added 1.3.0.0)
474 if( !m_carrier->compiler->go( filename, NULL, NULL, full_path ) )
475 return false;
476
477 // get the code
478 code = m_carrier->compiler->output();
479 // name it
480 code->name += path;
481
482 // log
483 EM_log( CK_LOG_FINE, "sporking %d %s...", count,
484 count == 1 ? "instance" : "instances" );
485
486 // spork it
487 while( count-- )
488 {
489 // spork (for now, spork_immediate arg is always false)
490 shred = m_carrier->vm->spork( code, NULL, FALSE );
491 // add args
492 shred->args = args;
493 }
494
495 // pop indent
496 EM_poplog();
497
498 return true;
499}
500
501
502
503
504//-----------------------------------------------------------------------------
505// name: compileCode()
506// desc: compile code directly
507//-----------------------------------------------------------------------------
508bool ChucK::compileCode( const std::string & code, const std::string & argsTogether, int count)
509{
510 // sanity check
511 if( !m_carrier->compiler )
512 {
513 // error
514 CK_FPRINTF_STDERR( "[chuck]: compileCode() invoked before initialization ...\n" );
515 return false;
516 }
517
518 vector<string> args;
519 Chuck_VM_Code * vm_code = NULL;
520 Chuck_VM_Shred * shred = NULL;
521
522 // log
523 EM_log( CK_LOG_FINE, "compiling string..." );
524 // push indent
525 EM_pushlog();
526
527 // falsify filename / path for various logs
528 string theThing = "compiled.code:" + argsTogether;
529 string fakefakeFilename = "<result file name goes here>";
530
531 // parse out command line arguments
532 if( !extract_args( theThing, fakefakeFilename, args ) )
533 {
534 // error
535 CK_FPRINTF_STDERR( "[chuck]: malformed filename with argument list...\n" );
536 CK_FPRINTF_STDERR( " --> '%s'", theThing.c_str() );
537 return false;
538 }
539
540 // PARAM
541 std::string workingDir = getParamString( CHUCK_PARAM_WORKING_DIRECTORY );
542
543 // construct full path to be associated with the file so me.sourceDir() works
544 std::string full_path = workingDir + "/compiled.code";
545
546 // parse, type-check, and emit (full_path added 1.3.0.0)
547 if( !m_carrier->compiler->go( "<compiled.code>", NULL, code.c_str(), full_path ) )
548 return false;
549
550 // get the code
551 vm_code = m_carrier->compiler->output();
552 // name it (no path to append)
553 vm_code->name += "compiled.code";
554
555 // log
556 EM_log( CK_LOG_FINE, "sporking %d %s...", count,
557 count == 1 ? "instance" : "instances" );
558
559 // spork it
560 while( count-- )
561 {
562 // spork (for now, spork_immediate arg is always false)
563 shred = m_carrier->vm->spork( vm_code, NULL, FALSE );
564 // add args
565 shred->args = args;
566 }
567
568 // pop indent
569 EM_poplog();
570
571 return true;
572}
573
574
575
576
577//-----------------------------------------------------------------------------
578// name: start()
579// desc: start chuck instance
580//-----------------------------------------------------------------------------
581bool ChucK::start()
582{
583 // sanity check
584 if( m_carrier->vm == NULL )
585 {
586 CK_FPRINTF_STDERR( "[chuck]: cannot start, VM not initialized...\n" );
587 return false;
588 }
589
590 // start the VM!
591 if( !m_carrier->vm->running() ) m_carrier->vm->start();
592
593 // return state
594 return m_carrier->vm->running();
595}
596
597
598
599
600//-----------------------------------------------------------------------------
601// name: run()
602// desc: run engine (call from host callback)
603//-----------------------------------------------------------------------------
604void ChucK::run( SAMPLE * input, SAMPLE * output, int numFrames )
605{
606 // make sure we started...
607 if( !m_carrier->vm->running() ) this->start();
608
609 // call the callback
610 m_carrier->vm->run( numFrames, input, output );
611}
612
613
614
615
616//-----------------------------------------------------------------------------
617// name: setExternalInt()
618// desc: send a message to set the value of an external int
619//-----------------------------------------------------------------------------
620t_CKBOOL ChucK::setExternalInt( const char * name, t_CKINT val )
621{
622 if( !m_carrier->vm->running() ) return FALSE;
623 return !m_carrier->vm->set_external_int( std::string( name ), val );
624}
625
626
627
628
629//-----------------------------------------------------------------------------
630// name: getExternalInt()
631// desc: send a message to get the value of an external int via callback
632//-----------------------------------------------------------------------------
633t_CKBOOL ChucK::getExternalInt( const char * name, void (* callback)(t_CKINT) )
634{
635 if( !m_carrier->vm->running() ) return FALSE;
636 return !m_carrier->vm->get_external_int( std::string( name ), callback );
637}
638
639
640
641
642//-----------------------------------------------------------------------------
643// name: setExternalFloat()
644// desc: send a message to set the value of an external float
645//-----------------------------------------------------------------------------
646t_CKBOOL ChucK::setExternalFloat( const char * name, t_CKFLOAT val )
647{
648 if( !m_carrier->vm->running() ) return FALSE;
649 return !m_carrier->vm->set_external_float( std::string( name ), val );
650}
651
652
653
654
655//-----------------------------------------------------------------------------
656// name: getExternalFloat()
657// desc: send a message to get the value of an external float via callback
658//-----------------------------------------------------------------------------
659t_CKBOOL ChucK::getExternalFloat( const char * name, void (* callback)(t_CKFLOAT) )
660{
661 if( !m_carrier->vm->running() ) return FALSE;
662 return !m_carrier->vm->get_external_float( std::string( name ), callback );
663}
664
665
666
667
668//-----------------------------------------------------------------------------
669// name: signalExternalEvent()
670// desc: send a message to signal an external event
671//-----------------------------------------------------------------------------
672t_CKBOOL ChucK::signalExternalEvent( const char * name )
673{
674 if( !m_carrier->vm->running() ) return FALSE;
675 return !m_carrier->vm->signal_external_event( std::string( name ) );
676}
677
678
679
680
681//-----------------------------------------------------------------------------
682// name: broadcastExternalEvent()
683// desc: send a message to broadcast an external event
684//-----------------------------------------------------------------------------
685t_CKBOOL ChucK::broadcastExternalEvent( const char * name )
686{
687 if( !m_carrier->vm->running() ) return FALSE;
688 return !m_carrier->vm->broadcast_external_event( std::string( name ) );
689}
690
691
692
693
694//-----------------------------------------------------------------------------
695// name: setChoutCallback()
696// desc: provide a callback where Chout print statements are routed
697//-----------------------------------------------------------------------------
698t_CKBOOL ChucK::setChoutCallback( void (* callback)(const char *) )
699{
700 if( !m_init || m_carrier->chout == NULL ) return FALSE;
701 m_carrier->chout->set_output_callback( callback );
702 return TRUE;
703}
704
705
706
707
708//-----------------------------------------------------------------------------
709// name: setCherrCallback()
710// desc: provide a callback where Cherr print statements are routed
711//-----------------------------------------------------------------------------
712t_CKBOOL ChucK::setCherrCallback( void (* callback)(const char *) )
713{
714 if( !m_init || m_carrier->cherr == NULL ) return FALSE;
715 m_carrier->cherr->set_output_callback( callback );
716 return TRUE;
717}
718
719
720
721
722//-----------------------------------------------------------------------------
723// name: setStdoutCallback()
724// desc: provide a callback where stdout print statements are routed
725//-----------------------------------------------------------------------------
726t_CKBOOL ChucK::setStdoutCallback( void (* callback)(const char *) )
727{
728 ck_set_stdout_callback( callback );
729 return TRUE;
730}
731
732
733
734
735//-----------------------------------------------------------------------------
736// name: setStderrCallback()
737// desc: provide a callback where <<< >>> and stdout print statements are routed
738//-----------------------------------------------------------------------------
739t_CKBOOL ChucK::setStderrCallback( void (* callback)(const char *) )
740{
741 ck_set_stderr_callback( callback );
742 return TRUE;
743}
744
745
746
747
748//-----------------------------------------------------------------------------
749// name: finalCleanup()
750// desc: provide a callback where <<< >>> and stdout print statements are routed
751//-----------------------------------------------------------------------------
752void ChucK::finalCleanup()
753{
754 // REFACTOR-2017 TODO Ge:
755 // stop le_cb, ...?
756}
757
758
759
760
761//-----------------------------------------------------------------------------
762// name: poop()
763// desc: --poop
764//-----------------------------------------------------------------------------
765void ChucK::poop()
766{
767 ::uh();
768}
core/chuck.h+0−173
@@ -1,173 +0,0 @@
1/*----------------------------------------------------------------------------
2 ChucK Concurrent, On-the-fly Audio Programming Language
3 Compiler and Virtual Machine
4
5 Copyright (c) 2003 Ge Wang and Perry R. Cook. All rights reserved.
6 http://chuck.stanford.edu/
7 http://chuck.cs.princeton.edu/
8
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.
13
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.
18
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 -----------------------------------------------------------------------------*/
24
25//-----------------------------------------------------------------------------
26// file: chuck.h
27// desc: chuck engine header; VM + compiler + state; no audio I/O
28// REFACTOR-2017
29//
30// author: Ge Wang (http://www.gewang.com/)
31// date: fall 2017
32//
33// additional authors:
34// Jack Atherton (lja@ccrma.stanford.edu)
35// Spencer Salazar (spencer@ccrma.stanford.edu)
36//-----------------------------------------------------------------------------
37#ifndef __CHUCK_H__
38#define __CHUCK_H__
39
40#include "chuck_compile.h"
41#include "chuck_dl.h"
42#include "chuck_vm.h"
43#include "chuck_shell.h"
44#include "chuck_carrier.h"
45#include <string>
46#include <map>
47
48
49
50
51// ChucK param names -- used in setParam(...) and getParam*(...)
52#define CHUCK_PARAM_SAMPLE_RATE "SAMPLE_RATE"
53#define CHUCK_PARAM_INPUT_CHANNELS "INPUT_CHANNELS"
54#define CHUCK_PARAM_OUTPUT_CHANNELS "OUTPUT_CHANNELS"
55#define CHUCK_PARAM_VM_ADAPTIVE "VM_ADAPTIVE"
56#define CHUCK_PARAM_VM_HALT "VM_HALT"
57#define CHUCK_PARAM_OTF_PORT "OTF_PORT"
58#define CHUCK_PARAM_LOG_LEVEL "LOG_LEVEL"
59#define CHUCK_PARAM_DUMP_INSTRUCTIONS "DUMP_INSTRUCTIONS"
60#define CHUCK_PARAM_AUTO_DEPEND "AUTO_DEPEND"
61#define CHUCK_PARAM_DEPRECATE_LEVEL "DEPRECATE_LEVEL"
62#define CHUCK_PARAM_WORKING_DIRECTORY "WORKING_DIRECTORY"
63#define CHUCK_PARAM_CHUGIN_DIRECTORY "CHUGIN_DIRECTORY"
64
65
66
67
68//-----------------------------------------------------------------------------
69// name: class ChucK
70// desc: ChucK system encapsulation
71//-----------------------------------------------------------------------------
72class ChucK
73{
74public:
75 // constructor
76 ChucK();
77 // desctructor
78 virtual ~ChucK();
79
80public:
81 // set parameter by name
82 // -- all params should have reasonable defaults
83 bool setParam( const std::string & name, t_CKINT value );
84 bool setParam( const std::string & name, t_CKFLOAT value );
85 bool setParam( const std::string & name, const std::string & value );
86 // get params
87 t_CKINT getParamInt( const std::string & key );
88 t_CKFLOAT getParamFloat( const std::string & key );
89 std::string getParamString( const std::string & key );
90
91public:
92 // compile a file (can be called anytime)
93 bool compileFile( const std::string & path, const std::string & argsTogether, int count = 1 );
94 // compile code directly
95 bool compileCode( const std::string & code, const std::string & argsTogether, int count = 1 );
96
97public:
98 // initialize ChucK (using params)
99 bool init();
100 // explicit start (optionally -- done as neede from run())
101 bool start();
102
103public:
104 // run engine (call from callback)
105 void run( SAMPLE * input, SAMPLE * output, int numFrames );
106
107public:
108 // additional native chuck bindings/types (use with extra caution)
109 bool bind( f_ck_query queryFunc, const std::string & name );
110
111public:
112 // get VM (dangerous)
113 Chuck_VM * vm() { return m_carrier->vm; }
114 // get compiler (dangerous)
115 Chuck_Compiler * compiler() { return m_carrier->compiler; }
116
117public:
118 // external variables - set and get
119 t_CKBOOL setExternalInt( const char * name, t_CKINT val );
120 t_CKBOOL getExternalInt( const char * name, void (* callback)(t_CKINT) );
121 t_CKBOOL setExternalFloat( const char * name, t_CKFLOAT val );
122 t_CKBOOL getExternalFloat( const char * name, void (* callback)(t_CKFLOAT) );
123 t_CKBOOL signalExternalEvent( const char * name );
124 t_CKBOOL broadcastExternalEvent( const char * name );
125
126public:
127 // external callback functions
128 t_CKBOOL setChoutCallback( void (* callback)(const char *) );
129 t_CKBOOL setCherrCallback( void (* callback)(const char *) );
130 static t_CKBOOL setStdoutCallback( void (* callback)(const char *) );
131 static t_CKBOOL setStderrCallback( void (* callback)(const char *) );
132
133public:
134 // TODO Ge: name choice? should this exist?
135 static void finalCleanup();
136
137protected:
138 // shutdown
139 bool shutdown();
140
141public: // static functions
142 // chuck version
143 static const char * version();
144 // chuck int size (in bits)
145 static t_CKUINT intSize();
146 // number of ChucK's
147 static t_CKUINT numVMs() { return o_numVMs; };
148 // --poop compatibilty
149 static void poop();
150
151protected:
152 // chuck version
153 static const char VERSION[];
154 // number of VMs -- managed from VM constructor/destructors
155 static t_CKUINT o_numVMs;
156
157protected:
158 // initialize default params
159 void initDefaultParams();
160
161protected:
162 // core elements: compiler, VM, etc.
163 Chuck_Carrier * m_carrier;
164 // chuck params
165 std::map<std::string, std::string> m_params;
166 // did user init?
167 t_CKBOOL m_init;
168};
169
170
171
172
173#endif
core/chuck.lex+0−328
@@ -1,328 +0,0 @@
1
2
3D [0-9]
4L [a-zA-Z_]
5H [a-fA-F0-9]
6E [Ee][+-]?{D}+
7FS (f|F|l|L)
8IS (u|U|l|L)*
9
10%{
11/*----------------------------------------------------------------------------
12 ChucK Concurrent, On-the-fly Audio Programming Language
13 Compiler and Virtual Machine
14
15 Copyright (c) 2004 Ge Wang and Perry R. Cook. All rights reserved.
16 http://chuck.cs.princeton.edu/
17 http://soundlab.cs.princeton.edu/
18
19 This program is free software; you can redistribute it and/or modify
20 it under the terms of the GNU General Public License as published by
21 the Free Software Foundation; either version 2 of the License, or
22 (at your option) any later version.
23
24 This program is distributed in the hope that it will be useful,
25 but WITHOUT ANY WARRANTY; without even the implied warranty of
26 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27 GNU General Public License for more details.
28
29 You should have received a copy of the GNU General Public License
30 along with this program; if not, write to the Free Software
31 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
32 U.S.A.
33-----------------------------------------------------------------------------*/
34
35//-----------------------------------------------------------------------------
36// file: chuck.yy.c
37// desc: chuck lexer
38//
39// author: Ge Wang (gewang.cs.princeton.edu) - generated by lex
40// Perry R. Cook (prc@cs.princeton.edu)
41//
42// based on the ansi C grammar by Jeff Lee, maintained by Jutta Degener
43//
44// date: Summer 2002
45//-----------------------------------------------------------------------------
46
47#include <stdlib.h>
48#include <string.h>
49#include "chuck_utils.h"
50#include "chuck_absyn.h"
51#include "chuck_errmsg.h"
52
53#ifndef __PLATFORM_WIN32__
54 #include "chuck.tab.h"
55#else
56 #include "chuck_win32.h"
57#endif
58
59
60
61// globals
62extern YYSTYPE yylval;
63int char_pos = 1;
64
65// define error handling
66#define YY_FATAL_ERROR(msg) EM_error2( 0, msg )
67
68#if defined(_cplusplus) || defined(__cplusplus)
69extern "C" {
70#endif
71
72 int yywrap(void);
73 void adjust();
74 c_str strip_lit( c_str str );
75 c_str alloc_str( c_str str );
76 long htol( c_str str );
77 int comment();
78 int block_comment();
79
80#if defined(_cplusplus) || defined(__cplusplus)
81}
82#endif
83
84// yywrap()
85int yywrap( void )
86{
87 char_pos = 1;
88 return 1;
89}
90
91// adjust()
92void adjust()
93{
94 EM_tokPos = char_pos;
95 char_pos += yyleng;
96}
97
98// strip
99c_str strip_lit( c_str str )
100{
101 str[strlen(str)-1] = '\0';
102 return str+1;
103}
104
105// alloc_str()
106c_str alloc_str( c_str str )
107{
108 c_str s = (c_str)malloc( strlen(str) + 1 );
109 strcpy( s, str );
110
111 return s;
112}
113
114// to long
115long htol( c_str str )
116{
117 char * c = str;
118 unsigned long n = 0;
119
120 // skip over 0x
121 c += 2;
122 while( *c )
123 {
124 n <<= 4;
125 switch( *c )
126 {
127 case '1': case '2': case '3': case '4': case '5':
128 case '6': case '7': case '8': case '9': case '0':
129 n += *c - '0';
130 break;
131
132 case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
133 n += *c - 'a' + 10;
134 break;
135
136 case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
137 n += *c - 'A' + 10;
138 break;
139 }
140 c++;
141 }
142
143 return n;
144}
145
146
147
148// block comment hack (thanks to unput/yytext_ptr inconsistency)
149#define block_comment_hack loop: \
150 while ((c = input()) != '*' && c != 0 && c != EOF ) \
151 if( c == '\n' ) EM_newline(); \
152 if( c == EOF ) adjust(); \
153 else if( (c1 = input()) != '/' && c != 0 ) \
154 { \
155 unput(c1); \
156 goto loop; \
157 } \
158 if( c != 0 ) adjust();
159
160// comment hack
161#define comment_hack \
162 while ((c = input()) != '\n' && c != '\r' && c != 0 && c != EOF ); \
163 if (c != 0) { \
164 adjust(); \
165 if (c == '\n') EM_newline(); \
166 }
167
168// .*\-\-> { adjust(); continue; }
169
170%}
171
172%%
173
174"//" { char c; adjust(); comment_hack; continue; }
175"<--" { char c; adjust(); comment_hack; continue; }
176"/*" { char c, c1; adjust(); block_comment_hack; continue; }
177" " { adjust(); continue; }
178"\t" { adjust(); continue; }
179"\r\n" { adjust(); EM_newline(); continue; }
180"\n" { adjust(); EM_newline(); continue; }
181
182"++" { adjust(); return PLUSPLUS; }
183"--" { adjust(); return MINUSMINUS; }
184"#(" { adjust(); return POUNDPAREN; }
185"%(" { adjust(); return PERCENTPAREN; }
186"@(" { adjust(); return ATPAREN; }
187
188"," { adjust(); return COMMA; }
189":" { adjust(); return COLON; }
190"." { adjust(); return DOT; }
191"+" { adjust(); return PLUS; }
192"-" { adjust(); return MINUS; }
193"*" { adjust(); return TIMES; }
194"/" { adjust(); return DIVIDE; }
195"%" { adjust(); return PERCENT; }
196"#" { adjust(); return POUND; }
197"$" { adjust(); return DOLLAR; }
198
199"::" { adjust(); return COLONCOLON; }
200"==" { adjust(); return EQ; }
201"!=" { adjust(); return NEQ; }
202"<" { adjust(); return LT; }
203">" { adjust(); return GT; }
204"<=" { adjust(); return LE; }
205">=" { adjust(); return GE; }
206"&&" { adjust(); return AND; }
207"||" { adjust(); return OR; }
208"&" { adjust(); return S_AND; }
209"|" { adjust(); return S_OR; }
210"^" { adjust(); return S_XOR; }
211">>" { adjust(); return SHIFT_RIGHT; }
212"<<" { adjust(); return SHIFT_LEFT; }
213"=" { adjust(); return ASSIGN; }
214"(" { adjust(); return LPAREN; }
215")" { adjust(); return RPAREN; }
216"[" { adjust(); return LBRACK; }
217"]" { adjust(); return RBRACK; }
218"{" { adjust(); return LBRACE; }
219"}" { adjust(); return RBRACE; }
220";" { adjust(); return SEMICOLON; }
221"?" { adjust(); return QUESTION; }
222"!" { adjust(); return EXCLAMATION; }
223"~" { adjust(); return TILDA; }
224for { adjust(); return FOR; }
225while { adjust(); return WHILE; }
226until { adjust(); return UNTIL; }
227repeat { adjust(); return LOOP; }
228continue { adjust(); return CONTINUE; }
229break { adjust(); return BREAK; }
230if { adjust(); return IF; }
231else { adjust(); return ELSE; }
232do { adjust(); return DO; }
233"<<<" { adjust(); return L_HACK; }
234">>>" { adjust(); return R_HACK; }
235
236return { adjust(); return RETURN; }
237
238function { adjust(); return FUNCTION; }
239fun { adjust(); return FUNCTION; }
240new { adjust(); return NEW; }
241class { adjust(); return CLASS; }
242interface { adjust(); return INTERFACE; }
243extends { adjust(); return EXTENDS; }
244implements { adjust(); return IMPLEMENTS; }
245public { adjust(); return PUBLIC; }
246protected { adjust(); return PROTECTED; }
247private { adjust(); return PRIVATE; }
248static { adjust(); return STATIC; }
249pure { adjust(); return ABSTRACT; }
250const { adjust(); return CONST; }
251spork { adjust(); return SPORK; }
252typeof { adjust(); return TYPEOF; }
253
254"=>" { adjust(); return CHUCK; }
255"=<" { adjust(); return UNCHUCK; }
256"!=>" { adjust(); return UNCHUCK; }
257"=^" { adjust(); return UPCHUCK; }
258"@=>" { adjust(); return AT_CHUCK; }
259"+=>" { adjust(); return PLUS_CHUCK; }
260"-=>" { adjust(); return MINUS_CHUCK; }
261"*=>" { adjust(); return TIMES_CHUCK; }
262"/=>" { adjust(); return DIVIDE_CHUCK; }
263"&=>" { adjust(); return S_AND_CHUCK; }
264"|=>" { adjust(); return S_OR_CHUCK; }
265"^=>" { adjust(); return S_XOR_CHUCK; }
266">>=>" { adjust(); return SHIFT_RIGHT_CHUCK; }
267"<<=>" { adjust(); return SHIFT_LEFT_CHUCK; }
268"%=>" { adjust(); return PERCENT_CHUCK; }
269"@" { adjust(); return AT_SYM; }
270"@@" { adjust(); return ATAT_SYM; }
271"->" { adjust(); return ARROW_RIGHT; }
272"<-" { adjust(); return ARROW_LEFT; }
273
2740[xX][0-9a-fA-F]+{IS}? { adjust(); yylval.ival=htol(yytext); return NUM; }
2750[cC][0-7]+{IS}? { adjust(); yylval.ival=atoi(yytext); return NUM; }
276[0-9]+{IS}? { adjust(); yylval.ival=atoi(yytext); return NUM; }
277([0-9]+"."[0-9]*)|([0-9]*"."[0-9]+) { adjust(); yylval.fval=atof(yytext); return FLOAT; }
278[A-Za-z_][A-Za-z0-9_]* { adjust(); yylval.sval=alloc_str(yytext); return ID; }
279\"(\\.|[^\\"])*\" { adjust(); yylval.sval=alloc_str(strip_lit(yytext)); return STRING_LIT; }
280`(\\.|[^\\`])*` { adjust(); yylval.sval=alloc_str(strip_lit(yytext)); return STRING_LIT; }
281'(\\.|[^\\'])' { adjust(); yylval.sval=alloc_str(strip_lit(yytext)); return CHAR_LIT; }
282
283. { adjust(); EM_error( EM_tokPos, "illegal token" ); }
284
285%%
286
287/*
288// comment
289int comment()
290{
291 char c;
292
293 while ((c = yyinput()) != '\n' && c != '\r' && c != 0 && c != EOF );
294
295 if (c != 0) {
296 adjust();
297 if (c == '\n') EM_newline();
298 }
299
300 return 0;
301}
302
303// block comment
304int block_comment()
305{
306 char c, c1;
307
308loop:
309 while ((c = yyinput()) != '*' && c != 0 && c != EOF )
310 if( c == '\n' ) EM_newline();
311
312 if( c == EOF )
313 {
314 adjust();
315 return 1;
316 }
317
318 if( (c1 = yyinput()) != '/' && c != 0 )
319 {
320 unput(c1);
321 goto loop;
322 }
323
324 if( c != 0 ) adjust();
325
326 return 0;
327}
328*/
core/chuck.tab.c+0−3141
@@ -1,3141 +0,0 @@
1/* A Bison parser, made by GNU Bison 3.0.4. */
2
3/* Bison implementation for Yacc-like parsers in C
4
5 Copyright (C) 1984, 1989-1990, 2000-2015 Free Software Foundation, Inc.
6
7 This program is free software: you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation, either version 3 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>. */
19
20/* As a special exception, you may create a larger work that contains
21 part or all of the Bison parser skeleton and distribute that work
22 under terms of your choice, so long as that work isn't itself a
23 parser generator using the skeleton or a modified version thereof
24 as a parser skeleton. Alternatively, if you modify or redistribute
25 the parser skeleton itself, you may (at your option) remove this
26 special exception, which will cause the skeleton and the resulting
27 Bison output files to be licensed under the GNU General Public
28 License without this special exception.
29
30 This special exception was added by the Free Software Foundation in
31 version 2.2 of Bison. */
32
33/* C LALR(1) parser skeleton written by Richard Stallman, by
34 simplifying the original so-called "semantic" parser. */
35
36/* All symbols defined below should begin with yy or YY, to avoid
37 infringing on user name space. This should be done even for local
38 variables, as they might otherwise be expanded by user macros.
39 There are some unavoidable exceptions within include files to
40 define necessary library symbols; they are noted "INFRINGES ON
41 USER NAME SPACE" below. */
42
43/* Identify Bison output. */
44#define YYBISON 1
45
46/* Bison version. */
47#define YYBISON_VERSION "3.0.4"
48
49/* Skeleton name. */
50#define YYSKELETON_NAME "yacc.c"
51
52/* Pure parsers. */
53#define YYPURE 0
54
55/* Push parsers. */
56#define YYPUSH 0
57
58/* Pull parsers. */
59#define YYPULL 1
60
61
62
63
64/* Copy the first part of user declarations. */
65#line 1 "chuck.y" /* yacc.c:339 */
66
67
68/*----------------------------------------------------------------------------
69 ChucK Concurrent, On-the-fly Audio Programming Language
70 Compiler and Virtual Machine
71
72 Copyright (c) 2004 Ge Wang and Perry R. Cook. All rights reserved.
73 http://chuck.cs.princeton.edu/
74 http://soundlab.cs.princeton.edu/
75
76 This program is free software; you can redistribute it and/or modify
77 it under the terms of the GNU General Public License as published by
78 the Free Software Foundation; either version 2 of the License, or
79 (at your option) any later version.
80
81 This program is distributed in the hope that it will be useful,
82 but WITHOUT ANY WARRANTY; without even the implied warranty of
83 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
84 GNU General Public License for more details.
85
86 You should have received a copy of the GNU General Public License
87 along with this program; if not, write to the Free Software
88 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
89 U.S.A.
90-----------------------------------------------------------------------------*/
91
92//-----------------------------------------------------------------------------
93// file: chuck.tab.c
94// desc: chuck parser
95//
96// author: Ge Wang (gewang@cs.princeton.edu) - generated by yacc
97// Perry R. Cook (prc@cs.princeton.edu)
98//
99// based in part on the ansi C grammar by Jeff Lee, maintained by Jutta Degener
100//
101// date: Summer 2002
102//-----------------------------------------------------------------------------
103#include <stdio.h>
104#include <string.h>
105#include <stdlib.h>
106#include "chuck_utils.h"
107#include "chuck_errmsg.h"
108#include "chuck_absyn.h"
109
110// function
111int yylex( void );
112
113void yyerror( char *s )
114{
115 EM_error( EM_tokPos, "%s", s );
116}
117
118a_Program g_program = NULL;
119
120
121#line 122 "chuck.tab.c" /* yacc.c:339 */
122
123# ifndef YY_NULLPTR
124# if defined __cplusplus && 201103L <= __cplusplus
125# define YY_NULLPTR nullptr
126# else
127# define YY_NULLPTR 0
128# endif
129# endif
130
131/* Enabling verbose error messages. */
132#ifdef YYERROR_VERBOSE
133# undef YYERROR_VERBOSE
134# define YYERROR_VERBOSE 1
135#else
136# define YYERROR_VERBOSE 0
137#endif
138
139/* In a future release of Bison, this section will be replaced
140 by #include "chuck.tab.h". */
141#ifndef YY_YY_CHUCK_TAB_H_INCLUDED
142# define YY_YY_CHUCK_TAB_H_INCLUDED
143/* Debug traces. */
144#ifndef YYDEBUG
145# define YYDEBUG 0
146#endif
147#if YYDEBUG
148extern int yydebug;
149#endif
150
151/* Token type. */
152#ifndef YYTOKENTYPE
153# define YYTOKENTYPE
154 enum yytokentype
155 {
156 ID = 258,
157 STRING_LIT = 259,
158 CHAR_LIT = 260,
159 NUM = 261,
160 FLOAT = 262,
161 POUND = 263,
162 COMMA = 264,
163 COLON = 265,
164 SEMICOLON = 266,
165 LPAREN = 267,
166 RPAREN = 268,
167 LBRACK = 269,
168 RBRACK = 270,
169 LBRACE = 271,
170 RBRACE = 272,
171 DOT = 273,
172 PLUS = 274,
173 MINUS = 275,
174 TIMES = 276,
175 DIVIDE = 277,
176 PERCENT = 278,
177 EQ = 279,
178 NEQ = 280,
179 LT = 281,
180 LE = 282,
181 GT = 283,
182 GE = 284,
183 AND = 285,
184 OR = 286,
185 ASSIGN = 287,
186 IF = 288,
187 THEN = 289,
188 ELSE = 290,
189 WHILE = 291,
190 FOR = 292,
191 DO = 293,
192 LOOP = 294,
193 BREAK = 295,
194 CONTINUE = 296,
195 NULL_TOK = 297,
196 FUNCTION = 298,
197 RETURN = 299,
198 QUESTION = 300,
199 EXCLAMATION = 301,
200 S_OR = 302,
201 S_AND = 303,
202 S_XOR = 304,
203 PLUSPLUS = 305,
204 MINUSMINUS = 306,
205 DOLLAR = 307,
206 POUNDPAREN = 308,
207 PERCENTPAREN = 309,
208 ATPAREN = 310,
209 SIMULT = 311,
210 PATTERN = 312,
211 CODE = 313,
212 TRANSPORT = 314,
213 HOST = 315,
214 TIME = 316,
215 WHENEVER = 317,
216 NEXT = 318,
217 UNTIL = 319,
218 EXTERNAL = 320,
219 EVERY = 321,
220 BEFORE = 322,
221 AFTER = 323,
222 AT = 324,
223 AT_SYM = 325,
224 ATAT_SYM = 326,
225 NEW = 327,
226 SIZEOF = 328,
227 TYPEOF = 329,
228 SAME = 330,
229 PLUS_CHUCK = 331,
230 MINUS_CHUCK = 332,
231 TIMES_CHUCK = 333,
232 DIVIDE_CHUCK = 334,
233 S_AND_CHUCK = 335,
234 S_OR_CHUCK = 336,
235 S_XOR_CHUCK = 337,
236 SHIFT_RIGHT_CHUCK = 338,
237 SHIFT_LEFT_CHUCK = 339,
238 PERCENT_CHUCK = 340,
239 SHIFT_RIGHT = 341,
240 SHIFT_LEFT = 342,
241 TILDA = 343,
242 CHUCK = 344,
243 COLONCOLON = 345,
244 S_CHUCK = 346,
245 AT_CHUCK = 347,
246 LEFT_S_CHUCK = 348,
247 UNCHUCK = 349,
248 UPCHUCK = 350,
249 CLASS = 351,
250 INTERFACE = 352,
251 EXTENDS = 353,
252 IMPLEMENTS = 354,
253 PUBLIC = 355,
254 PROTECTED = 356,
255 PRIVATE = 357,
256 STATIC = 358,
257 ABSTRACT = 359,
258 CONST = 360,
259 SPORK = 361,
260 ARROW_RIGHT = 362,
261 ARROW_LEFT = 363,
262 L_HACK = 364,
263 R_HACK = 365
264 };
265#endif
266
267/* Value type. */
268#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
269
270union YYSTYPE
271{
272#line 59 "chuck.y" /* yacc.c:355 */
273
274 int pos;
275 int ival;
276 double fval;
277 c_str sval;
278
279 a_Program program;
280 a_Section program_section;
281 a_Stmt_List stmt_list;
282 a_Class_Def class_def;
283 a_Class_Ext class_ext;
284 a_Class_Body class_body;
285 a_Stmt stmt;
286 a_Exp exp;
287 a_Func_Def func_def;
288 a_Var_Decl_List var_decl_list;
289 a_Var_Decl var_decl;
290 a_Type_Decl type_decl;
291 a_Arg_List arg_list;
292 a_Id_List id_list;
293 a_Array_Sub array_sub;
294 a_Complex complex_exp;
295 a_Polar polar_exp;
296 a_Vec vec_exp; // ge: added 1.3.5.3
297
298#line 299 "chuck.tab.c" /* yacc.c:355 */
299};
300
301typedef union YYSTYPE YYSTYPE;
302# define YYSTYPE_IS_TRIVIAL 1
303# define YYSTYPE_IS_DECLARED 1
304#endif
305
306
307extern YYSTYPE yylval;
308
309int yyparse (void);
310
311#endif /* !YY_YY_CHUCK_TAB_H_INCLUDED */
312
313/* Copy the second part of user declarations. */
314
315#line 316 "chuck.tab.c" /* yacc.c:358 */
316
317#ifdef short
318# undef short
319#endif
320
321#ifdef YYTYPE_UINT8
322typedef YYTYPE_UINT8 yytype_uint8;
323#else
324typedef unsigned char yytype_uint8;
325#endif
326
327#ifdef YYTYPE_INT8
328typedef YYTYPE_INT8 yytype_int8;
329#else
330typedef signed char yytype_int8;
331#endif
332
333#ifdef YYTYPE_UINT16
334typedef YYTYPE_UINT16 yytype_uint16;
335#else
336typedef unsigned short int yytype_uint16;
337#endif
338
339#ifdef YYTYPE_INT16
340typedef YYTYPE_INT16 yytype_int16;
341#else
342typedef short int yytype_int16;
343#endif
344
345#ifndef YYSIZE_T
346# ifdef __SIZE_TYPE__
347# define YYSIZE_T __SIZE_TYPE__
348# elif defined size_t
349# define YYSIZE_T size_t
350# elif ! defined YYSIZE_T
351# include <stddef.h> /* INFRINGES ON USER NAME SPACE */
352# define YYSIZE_T size_t
353# else
354# define YYSIZE_T unsigned int
355# endif
356#endif
357
358#define YYSIZE_MAXIMUM ((YYSIZE_T) -1)
359
360#ifndef YY_
361# if defined YYENABLE_NLS && YYENABLE_NLS
362# if ENABLE_NLS
363# include <libintl.h> /* INFRINGES ON USER NAME SPACE */
364# define YY_(Msgid) dgettext ("bison-runtime", Msgid)
365# endif
366# endif
367# ifndef YY_
368# define YY_(Msgid) Msgid
369# endif
370#endif
371
372#ifndef YY_ATTRIBUTE
373# if (defined __GNUC__ \
374 && (2 < __GNUC__ || (__GNUC__ == 2 && 96 <= __GNUC_MINOR__))) \
375 || defined __SUNPRO_C && 0x5110 <= __SUNPRO_C
376# define YY_ATTRIBUTE(Spec) __attribute__(Spec)
377# else
378# define YY_ATTRIBUTE(Spec) /* empty */
379# endif
380#endif
381
382#ifndef YY_ATTRIBUTE_PURE
383# define YY_ATTRIBUTE_PURE YY_ATTRIBUTE ((__pure__))
384#endif
385
386#ifndef YY_ATTRIBUTE_UNUSED
387# define YY_ATTRIBUTE_UNUSED YY_ATTRIBUTE ((__unused__))
388#endif
389
390#if !defined _Noreturn \
391 && (!defined __STDC_VERSION__ || __STDC_VERSION__ < 201112)
392# if defined _MSC_VER && 1200 <= _MSC_VER
393# define _Noreturn __declspec (noreturn)
394# else
395# define _Noreturn YY_ATTRIBUTE ((__noreturn__))
396# endif
397#endif
398
399/* Suppress unused-variable warnings by "using" E. */
400#if ! defined lint || defined __GNUC__
401# define YYUSE(E) ((void) (E))
402#else
403# define YYUSE(E) /* empty */
404#endif
405
406#if defined __GNUC__ && 407 <= __GNUC__ * 100 + __GNUC_MINOR__
407/* Suppress an incorrect diagnostic about yylval being uninitialized. */
408# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN \
409 _Pragma ("GCC diagnostic push") \
410 _Pragma ("GCC diagnostic ignored \"-Wuninitialized\"")\
411 _Pragma ("GCC diagnostic ignored \"-Wmaybe-uninitialized\"")
412# define YY_IGNORE_MAYBE_UNINITIALIZED_END \
413 _Pragma ("GCC diagnostic pop")
414#else
415# define YY_INITIAL_VALUE(Value) Value
416#endif
417#ifndef YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
418# define YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
419# define YY_IGNORE_MAYBE_UNINITIALIZED_END
420#endif
421#ifndef YY_INITIAL_VALUE
422# define YY_INITIAL_VALUE(Value) /* Nothing. */
423#endif
424
425
426#if ! defined yyoverflow || YYERROR_VERBOSE
427
428/* The parser invokes alloca or malloc; define the necessary symbols. */
429
430# ifdef YYSTACK_USE_ALLOCA
431# if YYSTACK_USE_ALLOCA
432# ifdef __GNUC__
433# define YYSTACK_ALLOC __builtin_alloca
434# elif defined __BUILTIN_VA_ARG_INCR
435# include <alloca.h> /* INFRINGES ON USER NAME SPACE */
436# elif defined _AIX
437# define YYSTACK_ALLOC __alloca
438# elif defined _MSC_VER
439# include <malloc.h> /* INFRINGES ON USER NAME SPACE */
440# define alloca _alloca
441# else
442# define YYSTACK_ALLOC alloca
443# if ! defined _ALLOCA_H && ! defined EXIT_SUCCESS
444# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
445 /* Use EXIT_SUCCESS as a witness for stdlib.h. */
446# ifndef EXIT_SUCCESS
447# define EXIT_SUCCESS 0
448# endif
449# endif
450# endif
451# endif
452# endif
453
454# ifdef YYSTACK_ALLOC
455 /* Pacify GCC's 'empty if-body' warning. */
456# define YYSTACK_FREE(Ptr) do { /* empty */; } while (0)
457# ifndef YYSTACK_ALLOC_MAXIMUM
458 /* The OS might guarantee only one guard page at the bottom of the stack,
459 and a page size can be as small as 4096 bytes. So we cannot safely
460 invoke alloca (N) if N exceeds 4096. Use a slightly smaller number
461 to allow for a few compiler-allocated temporary stack slots. */
462# define YYSTACK_ALLOC_MAXIMUM 4032 /* reasonable circa 2006 */
463# endif
464# else
465# define YYSTACK_ALLOC YYMALLOC
466# define YYSTACK_FREE YYFREE
467# ifndef YYSTACK_ALLOC_MAXIMUM
468# define YYSTACK_ALLOC_MAXIMUM YYSIZE_MAXIMUM
469# endif
470# if (defined __cplusplus && ! defined EXIT_SUCCESS \
471 && ! ((defined YYMALLOC || defined malloc) \
472 && (defined YYFREE || defined free)))
473# include <stdlib.h> /* INFRINGES ON USER NAME SPACE */
474# ifndef EXIT_SUCCESS
475# define EXIT_SUCCESS 0
476# endif
477# endif
478# ifndef YYMALLOC
479# define YYMALLOC malloc
480# if ! defined malloc && ! defined EXIT_SUCCESS
481void *malloc (YYSIZE_T); /* INFRINGES ON USER NAME SPACE */
482# endif
483# endif
484# ifndef YYFREE
485# define YYFREE free
486# if ! defined free && ! defined EXIT_SUCCESS
487void free (void *); /* INFRINGES ON USER NAME SPACE */
488# endif
489# endif
490# endif
491#endif /* ! defined yyoverflow || YYERROR_VERBOSE */
492
493
494#if (! defined yyoverflow \
495 && (! defined __cplusplus \
496 || (defined YYSTYPE_IS_TRIVIAL && YYSTYPE_IS_TRIVIAL)))
497
498/* A type that is properly aligned for any stack member. */
499union yyalloc
500{
501 yytype_int16 yyss_alloc;
502 YYSTYPE yyvs_alloc;
503};
504
505/* The size of the maximum gap between one aligned stack and the next. */
506# define YYSTACK_GAP_MAXIMUM (sizeof (union yyalloc) - 1)
507
508/* The size of an array large to enough to hold all stacks, each with
509 N elements. */
510# define YYSTACK_BYTES(N) \
511 ((N) * (sizeof (yytype_int16) + sizeof (YYSTYPE)) \
512 + YYSTACK_GAP_MAXIMUM)
513
514# define YYCOPY_NEEDED 1
515
516/* Relocate STACK from its old location to the new one. The
517 local variables YYSIZE and YYSTACKSIZE give the old and new number of
518 elements in the stack, and YYPTR gives the new location of the
519 stack. Advance YYPTR to a properly aligned location for the next
520 stack. */
521# define YYSTACK_RELOCATE(Stack_alloc, Stack) \
522 do \
523 { \
524 YYSIZE_T yynewbytes; \
525 YYCOPY (&yyptr->Stack_alloc, Stack, yysize); \
526 Stack = &yyptr->Stack_alloc; \
527 yynewbytes = yystacksize * sizeof (*Stack) + YYSTACK_GAP_MAXIMUM; \
528 yyptr += yynewbytes / sizeof (*yyptr); \
529 } \
530 while (0)
531
532#endif
533
534#if defined YYCOPY_NEEDED && YYCOPY_NEEDED
535/* Copy COUNT objects from SRC to DST. The source and destination do
536 not overlap. */
537# ifndef YYCOPY
538# if defined __GNUC__ && 1 < __GNUC__
539# define YYCOPY(Dst, Src, Count) \
540 __builtin_memcpy (Dst, Src, (Count) * sizeof (*(Src)))
541# else
542# define YYCOPY(Dst, Src, Count) \
543 do \
544 { \
545 YYSIZE_T yyi; \
546 for (yyi = 0; yyi < (Count); yyi++) \
547 (Dst)[yyi] = (Src)[yyi]; \
548 } \
549 while (0)
550# endif
551# endif
552#endif /* !YYCOPY_NEEDED */
553
554/* YYFINAL -- State number of the termination state. */
555#define YYFINAL 120
556/* YYLAST -- Last index in YYTABLE. */
557#define YYLAST 1202
558
559/* YYNTOKENS -- Number of terminals. */
560#define YYNTOKENS 111
561/* YYNNTS -- Number of nonterminals. */
562#define YYNNTS 58
563/* YYNRULES -- Number of rules. */
564#define YYNRULES 183
565/* YYNSTATES -- Number of states. */
566#define YYNSTATES 316
567
568/* YYTRANSLATE[YYX] -- Symbol number corresponding to YYX as returned
569 by yylex, with out-of-bounds checking. */
570#define YYUNDEFTOK 2
571#define YYMAXUTOK 365
572
573#define YYTRANSLATE(YYX) \
574 ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
575
576/* YYTRANSLATE[TOKEN-NUM] -- Symbol number corresponding to TOKEN-NUM
577 as returned by yylex, without out-of-bounds checking. */
578static const yytype_uint8 yytranslate[] =
579{
580 0, 2, 2, 2, 2, 2, 2, 2, 2, 2,
581 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
582 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
583 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
584 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
585 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
586 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
587 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
588 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
589 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
590 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
591 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
592 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
593 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
594 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
595 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
596 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
597 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
598 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
599 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
600 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
601 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
602 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
603 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
604 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
605 2, 2, 2, 2, 2, 2, 1, 2, 3, 4,
606 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
607 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
608 25, 26, 27, 28, 29, 30, 31, 32, 33, 34,
609 35, 36, 37, 38, 39, 40, 41, 42, 43, 44,
610 45, 46, 47, 48, 49, 50, 51, 52, 53, 54,
611 55, 56, 57, 58, 59, 60, 61, 62, 63, 64,
612 65, 66, 67, 68, 69, 70, 71, 72, 73, 74,
613 75, 76, 77, 78, 79, 80, 81, 82, 83, 84,
614 85, 86, 87, 88, 89, 90, 91, 92, 93, 94,
615 95, 96, 97, 98, 99, 100, 101, 102, 103, 104,
616 105, 106, 107, 108, 109, 110
617};
618
619#if YYDEBUG
620 /* YYRLINE[YYN] -- Source line where rule number YYN was defined. */
621static const yytype_uint16 yyrline[] =
622{
623 0, 182, 182, 183, 187, 188, 189, 193, 195, 197,
624 199, 204, 205, 206, 207, 211, 212, 216, 217, 222,
625 223, 224, 228, 232, 233, 237, 238, 242, 244, 246,
626 248, 253, 254, 255, 259, 260, 261, 262, 266, 267,
627 268, 272, 273, 277, 278, 287, 288, 293, 294, 298,
628 299, 303, 304, 308, 309, 310, 311, 313, 317, 318,
629 319, 320, 324, 326, 331, 333, 335, 337, 339, 341,
630 343, 348, 349, 353, 354, 358, 359, 363, 364, 369,
631 370, 375, 376, 381, 382, 386, 387, 388, 389, 390,
632 391, 395, 396, 400, 401, 402, 406, 411, 416, 421,
633 422, 423, 424, 425, 426, 427, 428, 429, 430, 431,
634 432, 433, 434, 438, 439, 443, 444, 449, 450, 455,
635 456, 461, 462, 467, 468, 473, 474, 479, 480, 482,
636 487, 488, 490, 492, 494, 499, 500, 502, 507, 508,
637 510, 515, 516, 518, 520, 525, 526, 531, 532, 537,
638 538, 540, 542, 544, 546, 548, 550, 557, 558, 559,
639 560, 561, 562, 567, 568, 573, 574, 576, 578, 580,
640 582, 584, 590, 591, 592, 593, 594, 595, 596, 597,
641 598, 599, 600, 601
642};
643#endif
644
645#if YYDEBUG || YYERROR_VERBOSE || 0
646/* YYTNAME[SYMBOL-NUM] -- String name of the symbol SYMBOL-NUM.
647 First, the terminals, then, starting at YYNTOKENS, nonterminals. */
648static const char *const yytname[] =
649{
650 "$end", "error", "$undefined", "ID", "STRING_LIT", "CHAR_LIT", "NUM",
651 "FLOAT", "POUND", "COMMA", "COLON", "SEMICOLON", "LPAREN", "RPAREN",
652 "LBRACK", "RBRACK", "LBRACE", "RBRACE", "DOT", "PLUS", "MINUS", "TIMES",
653 "DIVIDE", "PERCENT", "EQ", "NEQ", "LT", "LE", "GT", "GE", "AND", "OR",
654 "ASSIGN", "IF", "THEN", "ELSE", "WHILE", "FOR", "DO", "LOOP", "BREAK",
655 "CONTINUE", "NULL_TOK", "FUNCTION", "RETURN", "QUESTION", "EXCLAMATION",
656 "S_OR", "S_AND", "S_XOR", "PLUSPLUS", "MINUSMINUS", "DOLLAR",
657 "POUNDPAREN", "PERCENTPAREN", "ATPAREN", "SIMULT", "PATTERN", "CODE",
658 "TRANSPORT", "HOST", "TIME", "WHENEVER", "NEXT", "UNTIL", "EXTERNAL",
659 "EVERY", "BEFORE", "AFTER", "AT", "AT_SYM", "ATAT_SYM", "NEW", "SIZEOF",
660 "TYPEOF", "SAME", "PLUS_CHUCK", "MINUS_CHUCK", "TIMES_CHUCK",
661 "DIVIDE_CHUCK", "S_AND_CHUCK", "S_OR_CHUCK", "S_XOR_CHUCK",
662 "SHIFT_RIGHT_CHUCK", "SHIFT_LEFT_CHUCK", "PERCENT_CHUCK", "SHIFT_RIGHT",
663 "SHIFT_LEFT", "TILDA", "CHUCK", "COLONCOLON", "S_CHUCK", "AT_CHUCK",
664 "LEFT_S_CHUCK", "UNCHUCK", "UPCHUCK", "CLASS", "INTERFACE", "EXTENDS",
665 "IMPLEMENTS", "PUBLIC", "PROTECTED", "PRIVATE", "STATIC", "ABSTRACT",
666 "CONST", "SPORK", "ARROW_RIGHT", "ARROW_LEFT", "L_HACK", "R_HACK",
667 "$accept", "program", "program_section", "class_definition", "class_ext",
668 "class_body", "class_body2", "class_section", "iface_ext", "id_list",
669 "id_dot", "function_definition", "class_decl", "function_decl",
670 "static_decl", "type_decl_a", "type_decl_b", "type_decl", "type_decl2",
671 "arg_list", "statement_list", "statement", "jump_statement",
672 "selection_statement", "loop_statement", "code_segment",
673 "expression_statement", "expression", "chuck_expression",
674 "arrow_expression", "array_exp", "array_empty", "decl_expression",
675 "var_decl_list", "var_decl", "complex_exp", "polar_exp", "vec_exp",
676 "chuck_operator", "arrow_operator", "conditional_expression",
677 "logical_or_expression", "logical_and_expression",
678 "inclusive_or_expression", "exclusive_or_expression", "and_expression",
679 "equality_expression", "relational_expression", "shift_expression",
680 "additive_expression", "multiplicative_expression", "tilda_expression",
681 "cast_expression", "unary_expression", "unary_operator",
682 "dur_expression", "postfix_expression", "primary_expression", YY_NULLPTR
683};
684#endif
685
686# ifdef YYPRINT
687/* YYTOKNUM[NUM] -- (External) token number corresponding to the
688 (internal) symbol number NUM (which must be that of a token). */
689static const yytype_uint16 yytoknum[] =
690{
691 0, 256, 257, 258, 259, 260, 261, 262, 263, 264,
692 265, 266, 267, 268, 269, 270, 271, 272, 273, 274,
693 275, 276, 277, 278, 279, 280, 281, 282, 283, 284,
694 285, 286, 287, 288, 289, 290, 291, 292, 293, 294,
695 295, 296, 297, 298, 299, 300, 301, 302, 303, 304,
696 305, 306, 307, 308, 309, 310, 311, 312, 313, 314,
697 315, 316, 317, 318, 319, 320, 321, 322, 323, 324,
698 325, 326, 327, 328, 329, 330, 331, 332, 333, 334,
699 335, 336, 337, 338, 339, 340, 341, 342, 343, 344,
700 345, 346, 347, 348, 349, 350, 351, 352, 353, 354,
701 355, 356, 357, 358, 359, 360, 361, 362, 363, 364,
702 365
703};
704# endif
705
706#define YYPACT_NINF -265
707
708#define yypact_value_is_default(Yystate) \
709 (!!((Yystate) == (-265)))
710
711#define YYTABLE_NINF -42
712
713#define yytable_value_is_error(Yytable_value) \
714 0
715
716 /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
717 STATE-NUM. */
718static const yytype_int16 yypact[] =
719{
720 474, 14, -265, -265, -265, -265, -265, 691, 1093, 552,
721 -265, -265, -265, 43, 70, 73, 113, 627, 146, 96,
722 148, -265, 764, -265, 7, 7, 1093, 1093, 1093, 149,
723 26, 26, 7, 7, 157, -265, -42, -265, -3, 22,
724 74, 1093, 163, 240, -265, -265, 35, 11, -265, -265,
725 157, -265, 627, -265, -265, -265, -265, -265, 153, 100,
726 -7, -265, -265, -265, -265, -265, -265, 18, 135, 119,
727 120, 122, 86, 95, 48, 118, 106, 79, 123, -265,
728 7, 81, 94, -265, -265, -265, 159, 171, -265, 170,
729 172, 160, 1093, 1093, 837, 2, 1093, -265, -265, -265,
730 182, -265, -265, -265, 183, 184, 185, 1093, 129, 157,
731 186, -265, -265, 187, -265, 193, 157, 157, -265, 93,
732 -265, -265, 201, 201, -265, -265, 26, -265, -265, -265,
733 1093, -265, -265, -265, -265, -265, -265, -265, -265, -265,
734 -265, -265, -265, -265, -265, 1093, -265, -265, 1093, 7,
735 1093, 7, 7, 7, 7, 7, 7, 7, 7, 7,
736 7, 7, 7, 7, 7, 7, 7, 7, 7, 26,
737 -265, 64, 901, 202, -265, -265, -265, -265, 186, -265,
738 43, 136, 194, 195, 837, 197, 198, 199, -265, -265,
739 -265, -265, 200, -265, -265, 965, -265, 203, 157, -265,
740 -265, -265, 205, 0, 4, 204, 208, -265, -7, -265,
741 135, 206, 119, 120, 122, 86, 95, 95, 48, 48,
742 48, 48, 118, 118, 106, 106, 79, 79, 79, 123,
743 -265, 94, -265, 207, -265, -265, -265, -265, 627, 627,
744 1029, 1093, 1093, 627, 627, -265, 210, -265, 201, 318,
745 43, 201, 211, 318, 201, 214, 216, 203, 209, 7,
746 -265, 180, -265, 627, 213, 219, 220, -265, -265, -265,
747 -265, -265, 217, -265, 396, -265, -265, 140, 121, 318,
748 218, -265, 318, 38, -265, 627, -265, 627, 230, 231,
749 -265, -265, 201, 43, 232, -265, 233, 34, 157, 242,
750 -265, -265, -265, -265, -265, -265, -265, -265, -265, -265,
751 248, 75, 26, -265, -265, -265
752};
753
754 /* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM.
755 Performed when YYTABLE does not specify something else to do. Zero
756 means the default is an error. */
757static const yytype_uint8 yydefact[] =
758{
759 33, 172, 175, 176, 173, 174, 73, 0, 0, 0,
760 157, 158, 161, 0, 0, 0, 0, 0, 0, 0,
761 0, 34, 0, 160, 0, 0, 0, 0, 0, 0,
762 0, 0, 0, 0, 0, 159, 35, 36, 37, 0,
763 0, 0, 0, 33, 6, 5, 0, 40, 45, 46,
764 0, 4, 51, 56, 55, 54, 57, 53, 0, 75,
765 77, 177, 79, 178, 179, 180, 85, 115, 117, 119,
766 121, 123, 125, 127, 130, 135, 138, 141, 145, 147,
767 0, 149, 163, 165, 42, 183, 0, 0, 71, 0,
768 25, 0, 0, 0, 0, 0, 0, 60, 61, 58,
769 0, 172, 150, 151, 0, 0, 0, 0, 41, 0,
770 155, 154, 153, 93, 89, 91, 0, 0, 162, 0,
771 1, 3, 0, 0, 38, 39, 0, 86, 52, 74,
772 0, 101, 102, 103, 104, 110, 111, 112, 105, 106,
773 107, 99, 100, 108, 109, 0, 114, 113, 0, 0,
774 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
775 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
776 152, 0, 0, 0, 170, 171, 166, 182, 81, 72,
777 0, 43, 0, 0, 0, 0, 0, 0, 59, 96,
778 97, 98, 0, 87, 156, 0, 94, 95, 0, 90,
779 88, 181, 23, 0, 0, 47, 0, 76, 78, 80,
780 118, 0, 120, 122, 124, 126, 128, 129, 131, 133,
781 132, 134, 137, 136, 139, 140, 142, 143, 144, 146,
782 148, 164, 167, 0, 169, 82, 26, 44, 0, 0,
783 0, 0, 0, 0, 0, 83, 0, 92, 0, 33,
784 0, 0, 0, 33, 0, 0, 0, 48, 0, 0,
785 168, 62, 64, 0, 0, 0, 0, 70, 68, 84,
786 24, 21, 0, 15, 33, 20, 19, 13, 11, 33,
787 0, 22, 33, 0, 116, 0, 66, 0, 0, 0,
788 7, 18, 0, 0, 0, 9, 0, 0, 0, 0,
789 63, 67, 65, 69, 14, 12, 8, 10, 30, 28,
790 49, 0, 0, 29, 27, 50
791};
792
793 /* YYPGOTO[NTERM-NUM]. */
794static const yytype_int16 yypgoto[] =
795{
796 -265, 179, -265, 32, -265, -223, -16, -265, -265, -118,
797 -173, 44, -265, -265, -265, -265, -265, -30, -265, -50,
798 31, -15, -265, -265, -265, -264, -79, -4, -265, 124,
799 -74, 58, 116, -44, -33, -265, -265, -265, -265, -265,
800 8, -265, 125, 117, 133, 134, 138, -5, -17, -9,
801 -8, -18, 103, 10, -265, -265, 104, -265
802};
803
804 /* YYDEFGOTO[NTERM-NUM]. */
805static const yytype_int16 yydefgoto[] =
806{
807 -1, 42, 43, 271, 252, 272, 273, 274, 255, 203,
808 91, 275, 46, 47, 126, 48, 49, 50, 206, 299,
809 276, 52, 53, 54, 55, 56, 57, 58, 59, 60,
810 61, 197, 62, 114, 115, 63, 64, 65, 145, 148,
811 66, 67, 68, 69, 70, 71, 72, 73, 74, 75,
812 76, 77, 78, 79, 80, 81, 82, 83
813};
814
815 /* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM. If
816 positive, shift that token. If negative, reduce the rule whose
817 number is the opposite. If YYTABLE_NINF, syntax error. */
818static const yytype_int16 yytable[] =
819{
820 109, 110, 95, 86, 87, 204, 127, 236, 176, 117,
821 101, 2, 3, 4, 5, 184, 249, -41, 100, 7,
822 253, 8, 104, 105, 106, 108, 10, 11, 12, 108,
823 280, 51, 44, 309, 102, 103, 194, 119, 185, 196,
824 89, 108, 111, 112, 45, 308, 90, 314, 13, 149,
825 9, 297, 13, 23, -31, -31, 294, 24, 25, 296,
826 26, 27, 28, 150, 13, 193, 186, 101, 2, 3,
827 4, 5, 199, 200, 51, 44, 7, 277, 8, 31,
828 32, 33, 92, 128, 84, 93, 313, 45, 182, 183,
829 170, 9, 187, -32, -32, 35, 205, 116, 250, 251,
830 146, 147, 254, 192, 235, 240, 172, 97, 8, 130,
831 155, 156, 173, 40, 124, 125, 41, 26, 27, 28,
832 305, 157, 158, 159, 160, 94, 207, 165, 166, 167,
833 270, 122, 123, 278, 161, 162, 281, 163, 164, 230,
834 218, 219, 220, 221, 174, 175, 211, 226, 227, 228,
835 216, 217, 222, 223, 247, 224, 225, 176, 96, 98,
836 113, 107, 118, 120, 129, 151, 152, 168, 233, 153,
837 154, 171, 177, 41, 304, 169, 131, 132, 133, 134,
838 135, 136, 137, 138, 139, 140, 178, 179, 181, 141,
839 180, 87, 142, 188, 143, 144, 189, 190, 191, 84,
840 8, 195, 198, 201, 202, 234, 237, 238, 239, 241,
841 242, 258, 243, 244, 248, 285, 259, 246, 256, 293,
842 260, 283, 121, 261, 262, 269, 287, 279, 267, 268,
843 282, 245, 288, 289, 290, 295, 264, 265, 266, 292,
844 -2, 302, 303, 1, 2, 3, 4, 5, 286, 306,
845 307, 6, 7, 298, 8, 311, 9, 312, 291, 10,
846 11, 12, 315, 257, 209, 310, 13, 284, 212, 208,
847 300, 229, 301, 14, 210, 231, 15, 16, 17, 18,
848 19, 20, 298, 21, 22, 213, 23, 214, 0, 0,
849 24, 25, 215, 26, 27, 28, 0, 0, 0, 0,
850 0, 0, 0, 0, 29, 30, 0, 0, 0, 0,
851 0, 0, 31, 32, 33, 34, 0, 0, 0, 0,
852 0, 1, 2, 3, 4, 5, 0, 0, 35, 6,
853 7, 0, 8, 0, 9, -16, 0, 10, 11, 12,
854 36, 37, 38, 39, 13, 0, 40, 0, 0, 41,
855 0, 14, 0, 0, 15, 16, 17, 18, 19, 20,
856 0, 21, 22, 0, 23, 0, 0, 0, 24, 25,
857 0, 26, 27, 28, 0, 0, 0, 0, 0, 0,
858 0, 0, 29, 30, 0, 0, 0, 0, 0, 0,
859 31, 32, 33, 34, 0, 0, 0, 0, 0, 1,
860 2, 3, 4, 5, 0, 0, 35, 6, 7, 0,
861 8, 0, 9, -17, 0, 10, 11, 12, 36, 37,
862 38, 39, 13, 0, 40, 0, 0, 41, 0, 14,
863 0, 0, 15, 16, 17, 18, 19, 20, 0, 21,
864 22, 0, 23, 0, 0, 0, 24, 25, 0, 26,
865 27, 28, 0, 0, 0, 0, 0, 0, 0, 0,
866 29, 30, 0, 0, 0, 0, 0, 0, 31, 32,
867 33, 34, 0, 0, 0, 0, 0, 1, 2, 3,
868 4, 5, 0, 0, 35, 6, 7, 0, 8, 0,
869 9, 0, 0, 10, 11, 12, 36, 37, 38, 39,
870 13, 0, 40, 0, 0, 41, 0, 14, 0, 0,
871 15, 16, 17, 18, 19, 20, 0, 21, 22, 0,
872 23, 0, 0, 0, 24, 25, 0, 26, 27, 28,
873 0, 0, 0, 0, 0, 0, 0, 0, 29, 30,
874 0, 0, 0, 0, 0, 0, 31, 32, 33, 34,
875 0, 0, 0, 0, 0, 1, 2, 3, 4, 5,
876 0, 0, 35, 6, 7, 0, 8, 0, 9, 88,
877 0, 10, 11, 12, 36, 37, 38, 39, 13, 0,
878 40, 0, 0, 41, 0, 14, 0, 0, 15, 16,
879 17, 18, 19, 20, 0, 0, 22, 0, 23, 0,
880 0, 0, 24, 25, 0, 26, 27, 28, 0, 0,
881 0, 0, 0, 0, 0, 0, 29, 30, 0, 0,
882 0, 0, 0, 0, 31, 32, 33, 34, 0, 0,
883 1, 2, 3, 4, 5, 0, 0, 0, 6, 7,
884 35, 8, 0, 9, 0, 0, 10, 11, 12, 0,
885 0, 0, 0, 13, 0, 39, 0, 0, 40, 0,
886 14, 41, 0, 15, 16, 17, 18, 19, 20, 0,
887 0, 22, 0, 23, 0, 0, 0, 24, 25, 0,
888 26, 27, 28, 0, 0, 0, 0, 0, 0, 0,
889 0, 29, 30, 0, 1, 2, 3, 4, 5, 31,
890 32, 33, 34, 7, 85, 8, 0, 0, 0, 0,
891 10, 11, 12, 0, 0, 35, 0, 13, 0, 0,
892 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
893 39, 0, 0, 40, 0, 0, 41, 23, 0, 0,
894 0, 24, 25, 0, 26, 27, 28, 0, 0, 0,
895 0, 0, 0, 0, 0, 0, 30, 0, 0, 0,
896 0, 0, 0, 31, 32, 33, 34, 1, 2, 3,
897 4, 5, 0, 0, 0, 99, 7, 0, 8, 35,
898 0, 0, 0, 10, 11, 12, 0, 0, 0, 0,
899 13, 0, 0, 0, 39, 0, 0, 40, 0, 0,
900 41, 0, 0, 0, 0, 0, 0, 0, 0, 0,
901 23, 0, 0, 0, 24, 25, 0, 26, 27, 28,
902 0, 0, 0, 0, 0, 0, 0, 0, 0, 30,
903 0, 0, 0, 0, 0, 0, 31, 32, 33, 34,
904 1, 2, 3, 4, 5, 0, 0, 0, 6, 7,
905 0, 8, 35, 0, 0, 0, 10, 11, 12, 0,
906 0, 0, 0, 13, 0, 0, 0, 39, 0, 0,
907 40, 0, 0, 41, 0, 0, 0, 0, 0, 0,
908 0, 0, 0, 23, 0, 0, 0, 24, 25, 0,
909 26, 27, 28, 0, 0, 0, 0, 0, 0, 0,
910 0, 0, 30, 0, 1, 2, 3, 4, 5, 31,
911 32, 33, 34, 7, 232, 8, 0, 0, 0, 0,
912 10, 11, 12, 0, 0, 35, 0, 13, 0, 0,
913 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
914 39, 0, 0, 40, 0, 0, 41, 23, 0, 0,
915 0, 24, 25, 0, 26, 27, 28, 0, 0, 0,
916 0, 0, 0, 0, 0, 0, 30, 0, 1, 2,
917 3, 4, 5, 31, 32, 33, 34, 7, 0, 8,
918 245, 0, 0, 0, 10, 11, 12, 0, 0, 35,
919 0, 13, 0, 0, 0, 0, 0, 0, 0, 0,
920 0, 0, 0, 0, 39, 0, 0, 40, 0, 0,
921 41, 23, 0, 0, 0, 24, 25, 0, 26, 27,
922 28, 0, 0, 0, 0, 0, 0, 0, 0, 0,
923 30, 0, 1, 2, 3, 4, 5, 31, 32, 33,
924 34, 7, 263, 8, 0, 0, 0, 0, 10, 11,
925 12, 0, 0, 35, 0, 13, 0, 0, 0, 0,
926 0, 0, 0, 0, 0, 0, 0, 0, 39, 0,
927 0, 40, 0, 0, 41, 23, 0, 0, 0, 24,
928 25, 0, 26, 27, 28, 0, 0, 0, 0, 0,
929 0, 0, 0, 0, 30, 0, 1, 2, 3, 4,
930 5, 31, 32, 33, 34, 7, 0, 8, 0, 0,
931 0, 0, 10, 11, 12, 0, 0, 35, 0, 13,
932 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
933 0, 0, 39, 0, 0, 40, 0, 0, 41, 23,
934 0, 0, 0, 24, 25, 0, 26, 27, 28, 0,
935 0, 0, 0, 0, 0, 0, 0, 0, 30, 0,
936 0, 0, 0, 0, 0, 31, 32, 33, 34, 0,
937 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
938 0, 35, 0, 0, 0, 0, 0, 0, 0, 0,
939 0, 0, 0, 0, 0, 0, 39, 0, 0, 40,
940 0, 0, 41
941};
942
943static const yytype_int16 yycheck[] =
944{
945 30, 31, 17, 7, 8, 123, 50, 180, 82, 39,
946 3, 4, 5, 6, 7, 94, 16, 3, 22, 12,
947 16, 14, 26, 27, 28, 3, 19, 20, 21, 3,
948 253, 0, 0, 297, 24, 25, 110, 41, 36, 113,
949 9, 3, 32, 33, 0, 11, 3, 311, 26, 31,
950 16, 13, 26, 46, 96, 97, 279, 50, 51, 282,
951 53, 54, 55, 45, 26, 109, 64, 3, 4, 5,
952 6, 7, 116, 117, 43, 43, 12, 250, 14, 72,
953 73, 74, 12, 52, 70, 12, 11, 43, 92, 93,
954 80, 16, 96, 96, 97, 88, 126, 75, 98, 99,
955 107, 108, 98, 107, 178, 184, 12, 11, 14, 9,
956 24, 25, 18, 106, 103, 104, 109, 53, 54, 55,
957 293, 26, 27, 28, 29, 12, 130, 21, 22, 23,
958 248, 96, 97, 251, 86, 87, 254, 19, 20, 169,
959 157, 158, 159, 160, 50, 51, 150, 165, 166, 167,
960 155, 156, 161, 162, 198, 163, 164, 231, 12, 11,
961 3, 12, 88, 0, 11, 30, 47, 88, 172, 49,
962 48, 90, 13, 109, 292, 52, 76, 77, 78, 79,
963 80, 81, 82, 83, 84, 85, 15, 17, 28, 89,
964 18, 195, 92, 11, 94, 95, 13, 13, 13, 70,
965 14, 14, 9, 110, 3, 3, 70, 13, 13, 12,
966 12, 3, 13, 13, 9, 35, 10, 14, 14, 98,
967 13, 12, 43, 238, 239, 15, 13, 16, 243, 244,
968 16, 15, 13, 13, 17, 17, 240, 241, 242, 99,
969 0, 11, 11, 3, 4, 5, 6, 7, 263, 17,
970 17, 11, 12, 283, 14, 13, 16, 9, 274, 19,
971 20, 21, 312, 205, 148, 298, 26, 259, 151, 145,
972 285, 168, 287, 33, 149, 171, 36, 37, 38, 39,
973 40, 41, 312, 43, 44, 152, 46, 153, -1, -1,
974 50, 51, 154, 53, 54, 55, -1, -1, -1, -1,
975 -1, -1, -1, -1, 64, 65, -1, -1, -1, -1,
976 -1, -1, 72, 73, 74, 75, -1, -1, -1, -1,
977 -1, 3, 4, 5, 6, 7, -1, -1, 88, 11,
978 12, -1, 14, -1, 16, 17, -1, 19, 20, 21,
979 100, 101, 102, 103, 26, -1, 106, -1, -1, 109,
980 -1, 33, -1, -1, 36, 37, 38, 39, 40, 41,
981 -1, 43, 44, -1, 46, -1, -1, -1, 50, 51,
982 -1, 53, 54, 55, -1, -1, -1, -1, -1, -1,
983 -1, -1, 64, 65, -1, -1, -1, -1, -1, -1,
984 72, 73, 74, 75, -1, -1, -1, -1, -1, 3,
985 4, 5, 6, 7, -1, -1, 88, 11, 12, -1,
986 14, -1, 16, 17, -1, 19, 20, 21, 100, 101,
987 102, 103, 26, -1, 106, -1, -1, 109, -1, 33,
988 -1, -1, 36, 37, 38, 39, 40, 41, -1, 43,
989 44, -1, 46, -1, -1, -1, 50, 51, -1, 53,
990 54, 55, -1, -1, -1, -1, -1, -1, -1, -1,
991 64, 65, -1, -1, -1, -1, -1, -1, 72, 73,
992 74, 75, -1, -1, -1, -1, -1, 3, 4, 5,
993 6, 7, -1, -1, 88, 11, 12, -1, 14, -1,
994 16, -1, -1, 19, 20, 21, 100, 101, 102, 103,
995 26, -1, 106, -1, -1, 109, -1, 33, -1, -1,
996 36, 37, 38, 39, 40, 41, -1, 43, 44, -1,
997 46, -1, -1, -1, 50, 51, -1, 53, 54, 55,
998 -1, -1, -1, -1, -1, -1, -1, -1, 64, 65,
999 -1, -1, -1, -1, -1, -1, 72, 73, 74, 75,
1000 -1, -1, -1, -1, -1, 3, 4, 5, 6, 7,
1001 -1, -1, 88, 11, 12, -1, 14, -1, 16, 17,
1002 -1, 19, 20, 21, 100, 101, 102, 103, 26, -1,
1003 106, -1, -1, 109, -1, 33, -1, -1, 36, 37,
1004 38, 39, 40, 41, -1, -1, 44, -1, 46, -1,
1005 -1, -1, 50, 51, -1, 53, 54, 55, -1, -1,
1006 -1, -1, -1, -1, -1, -1, 64, 65, -1, -1,
1007 -1, -1, -1, -1, 72, 73, 74, 75, -1, -1,
1008 3, 4, 5, 6, 7, -1, -1, -1, 11, 12,
1009 88, 14, -1, 16, -1, -1, 19, 20, 21, -1,
1010 -1, -1, -1, 26, -1, 103, -1, -1, 106, -1,
1011 33, 109, -1, 36, 37, 38, 39, 40, 41, -1,
1012 -1, 44, -1, 46, -1, -1, -1, 50, 51, -1,
1013 53, 54, 55, -1, -1, -1, -1, -1, -1, -1,
1014 -1, 64, 65, -1, 3, 4, 5, 6, 7, 72,
1015 73, 74, 75, 12, 13, 14, -1, -1, -1, -1,
1016 19, 20, 21, -1, -1, 88, -1, 26, -1, -1,
1017 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
1018 103, -1, -1, 106, -1, -1, 109, 46, -1, -1,
1019 -1, 50, 51, -1, 53, 54, 55, -1, -1, -1,
1020 -1, -1, -1, -1, -1, -1, 65, -1, -1, -1,
1021 -1, -1, -1, 72, 73, 74, 75, 3, 4, 5,
1022 6, 7, -1, -1, -1, 11, 12, -1, 14, 88,
1023 -1, -1, -1, 19, 20, 21, -1, -1, -1, -1,
1024 26, -1, -1, -1, 103, -1, -1, 106, -1, -1,
1025 109, -1, -1, -1, -1, -1, -1, -1, -1, -1,
1026 46, -1, -1, -1, 50, 51, -1, 53, 54, 55,
1027 -1, -1, -1, -1, -1, -1, -1, -1, -1, 65,
1028 -1, -1, -1, -1, -1, -1, 72, 73, 74, 75,
1029 3, 4, 5, 6, 7, -1, -1, -1, 11, 12,
1030 -1, 14, 88, -1, -1, -1, 19, 20, 21, -1,
1031 -1, -1, -1, 26, -1, -1, -1, 103, -1, -1,
1032 106, -1, -1, 109, -1, -1, -1, -1, -1, -1,
1033 -1, -1, -1, 46, -1, -1, -1, 50, 51, -1,
1034 53, 54, 55, -1, -1, -1, -1, -1, -1, -1,
1035 -1, -1, 65, -1, 3, 4, 5, 6, 7, 72,
1036 73, 74, 75, 12, 13, 14, -1, -1, -1, -1,
1037 19, 20, 21, -1, -1, 88, -1, 26, -1, -1,
1038 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
1039 103, -1, -1, 106, -1, -1, 109, 46, -1, -1,
1040 -1, 50, 51, -1, 53, 54, 55, -1, -1, -1,
1041 -1, -1, -1, -1, -1, -1, 65, -1, 3, 4,
1042 5, 6, 7, 72, 73, 74, 75, 12, -1, 14,
1043 15, -1, -1, -1, 19, 20, 21, -1, -1, 88,
1044 -1, 26, -1, -1, -1, -1, -1, -1, -1, -1,
1045 -1, -1, -1, -1, 103, -1, -1, 106, -1, -1,
1046 109, 46, -1, -1, -1, 50, 51, -1, 53, 54,
1047 55, -1, -1, -1, -1, -1, -1, -1, -1, -1,
1048 65, -1, 3, 4, 5, 6, 7, 72, 73, 74,
1049 75, 12, 13, 14, -1, -1, -1, -1, 19, 20,
1050 21, -1, -1, 88, -1, 26, -1, -1, -1, -1,
1051 -1, -1, -1, -1, -1, -1, -1, -1, 103, -1,
1052 -1, 106, -1, -1, 109, 46, -1, -1, -1, 50,
1053 51, -1, 53, 54, 55, -1, -1, -1, -1, -1,
1054 -1, -1, -1, -1, 65, -1, 3, 4, 5, 6,
1055 7, 72, 73, 74, 75, 12, -1, 14, -1, -1,
1056 -1, -1, 19, 20, 21, -1, -1, 88, -1, 26,
1057 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
1058 -1, -1, 103, -1, -1, 106, -1, -1, 109, 46,
1059 -1, -1, -1, 50, 51, -1, 53, 54, 55, -1,
1060 -1, -1, -1, -1, -1, -1, -1, -1, 65, -1,
1061 -1, -1, -1, -1, -1, 72, 73, 74, 75, -1,
1062 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
1063 -1, 88, -1, -1, -1, -1, -1, -1, -1, -1,
1064 -1, -1, -1, -1, -1, -1, 103, -1, -1, 106,
1065 -1, -1, 109
1066};
1067
1068 /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
1069 symbol of state STATE-NUM. */
1070static const yytype_uint8 yystos[] =
1071{
1072 0, 3, 4, 5, 6, 7, 11, 12, 14, 16,
1073 19, 20, 21, 26, 33, 36, 37, 38, 39, 40,
1074 41, 43, 44, 46, 50, 51, 53, 54, 55, 64,
1075 65, 72, 73, 74, 75, 88, 100, 101, 102, 103,
1076 106, 109, 112, 113, 114, 122, 123, 124, 126, 127,
1077 128, 131, 132, 133, 134, 135, 136, 137, 138, 139,
1078 140, 141, 143, 146, 147, 148, 151, 152, 153, 154,
1079 155, 156, 157, 158, 159, 160, 161, 162, 163, 164,
1080 165, 166, 167, 168, 70, 13, 138, 138, 17, 131,
1081 3, 121, 12, 12, 12, 132, 12, 11, 11, 11,
1082 138, 3, 164, 164, 138, 138, 138, 12, 3, 128,
1083 128, 164, 164, 3, 144, 145, 75, 128, 88, 138,
1084 0, 112, 96, 97, 103, 104, 125, 144, 131, 11,
1085 9, 76, 77, 78, 79, 80, 81, 82, 83, 84,
1086 85, 89, 92, 94, 95, 149, 107, 108, 150, 31,
1087 45, 30, 47, 49, 48, 24, 25, 26, 27, 28,
1088 29, 86, 87, 19, 20, 21, 22, 23, 88, 52,
1089 164, 90, 12, 18, 50, 51, 141, 13, 15, 17,
1090 18, 28, 138, 138, 137, 36, 64, 138, 11, 13,
1091 13, 13, 138, 144, 141, 14, 141, 142, 9, 144,
1092 144, 110, 3, 120, 120, 128, 129, 138, 140, 143,
1093 153, 138, 154, 155, 156, 157, 158, 158, 159, 159,
1094 159, 159, 160, 160, 161, 161, 162, 162, 162, 163,
1095 128, 167, 13, 138, 3, 141, 121, 70, 13, 13,
1096 137, 12, 12, 13, 13, 15, 14, 144, 9, 16,
1097 98, 99, 115, 16, 98, 119, 14, 142, 3, 10,
1098 13, 132, 132, 13, 138, 138, 138, 132, 132, 15,
1099 120, 114, 116, 117, 118, 122, 131, 121, 120, 16,
1100 116, 120, 16, 12, 151, 35, 132, 13, 13, 13,
1101 17, 117, 99, 98, 116, 17, 116, 13, 128, 130,
1102 132, 132, 11, 11, 120, 121, 17, 17, 11, 136,
1103 145, 13, 9, 11, 136, 130
1104};
1105
1106 /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */
1107static const yytype_uint8 yyr1[] =
1108{
1109 0, 111, 112, 112, 113, 113, 113, 114, 114, 114,
1110 114, 115, 115, 115, 115, 116, 116, 117, 117, 118,
1111 118, 118, 119, 120, 120, 121, 121, 122, 122, 122,
1112 122, 123, 123, 123, 124, 124, 124, 124, 125, 125,
1113 125, 126, 126, 127, 127, 128, 128, 129, 129, 130,
1114 130, 131, 131, 132, 132, 132, 132, 132, 133, 133,
1115 133, 133, 134, 134, 135, 135, 135, 135, 135, 135,
1116 135, 136, 136, 137, 137, 138, 138, 139, 139, 140,
1117 140, 141, 141, 142, 142, 143, 143, 143, 143, 143,
1118 143, 144, 144, 145, 145, 145, 146, 147, 148, 149,
1119 149, 149, 149, 149, 149, 149, 149, 149, 149, 149,
1120 149, 149, 149, 150, 150, 151, 151, 152, 152, 153,
1121 153, 154, 154, 155, 155, 156, 156, 157, 157, 157,
1122 158, 158, 158, 158, 158, 159, 159, 159, 160, 160,
1123 160, 161, 161, 161, 161, 162, 162, 163, 163, 164,
1124 164, 164, 164, 164, 164, 164, 164, 165, 165, 165,
1125 165, 165, 165, 166, 166, 167, 167, 167, 167, 167,
1126 167, 167, 168, 168, 168, 168, 168, 168, 168, 168,
1127 168, 168, 168, 168
1128};
1129
1130 /* YYR2[YYN] -- Number of symbols on the right hand side of rule YYN. */
1131static const yytype_uint8 yyr2[] =
1132{
1133 0, 2, 1, 2, 1, 1, 1, 6, 7, 6,
1134 7, 2, 4, 2, 4, 1, 0, 1, 2, 1,
1135 1, 1, 2, 1, 3, 1, 3, 8, 7, 8,
1136 7, 1, 1, 0, 1, 1, 1, 1, 1, 1,
1137 0, 1, 2, 3, 4, 1, 1, 1, 2, 2,
1138 4, 1, 2, 1, 1, 1, 1, 1, 2, 3,
1139 2, 2, 5, 7, 5, 7, 6, 7, 5, 7,
1140 5, 2, 3, 1, 2, 1, 3, 1, 3, 1,
1141 3, 3, 4, 2, 3, 1, 2, 3, 3, 2,
1142 3, 1, 3, 1, 2, 2, 3, 3, 3, 1,
1143 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1144 1, 1, 1, 1, 1, 1, 5, 1, 3, 1,
1145 3, 1, 3, 1, 3, 1, 3, 1, 3, 3,
1146 1, 3, 3, 3, 3, 1, 3, 3, 1, 3,
1147 3, 1, 3, 3, 3, 1, 3, 1, 3, 1,
1148 2, 2, 2, 2, 2, 2, 3, 1, 1, 1,
1149 1, 1, 2, 1, 3, 1, 2, 3, 4, 3,
1150 2, 2, 1, 1, 1, 1, 1, 1, 1, 1,
1151 1, 3, 3, 2
1152};
1153
1154
1155#define yyerrok (yyerrstatus = 0)
1156#define yyclearin (yychar = YYEMPTY)
1157#define YYEMPTY (-2)
1158#define YYEOF 0
1159
1160#define YYACCEPT goto yyacceptlab
1161#define YYABORT goto yyabortlab
1162#define YYERROR goto yyerrorlab
1163
1164
1165#define YYRECOVERING() (!!yyerrstatus)
1166
1167#define YYBACKUP(Token, Value) \
1168do \
1169 if (yychar == YYEMPTY) \
1170 { \
1171 yychar = (Token); \
1172 yylval = (Value); \
1173 YYPOPSTACK (yylen); \
1174 yystate = *yyssp; \
1175 goto yybackup; \
1176 } \
1177 else \
1178 { \
1179 yyerror (YY_("syntax error: cannot back up")); \
1180 YYERROR; \
1181 } \
1182while (0)
1183
1184/* Error token number */
1185#define YYTERROR 1
1186#define YYERRCODE 256
1187
1188
1189
1190/* Enable debugging if requested. */
1191#if YYDEBUG
1192
1193# ifndef YYFPRINTF
1194# include <stdio.h> /* INFRINGES ON USER NAME SPACE */
1195# define YYFPRINTF fprintf
1196# endif
1197
1198# define YYDPRINTF(Args) \
1199do { \
1200 if (yydebug) \
1201 YYFPRINTF Args; \
1202} while (0)
1203
1204/* This macro is provided for backward compatibility. */
1205#ifndef YY_LOCATION_PRINT
1206# define YY_LOCATION_PRINT(File, Loc) ((void) 0)
1207#endif
1208
1209
1210# define YY_SYMBOL_PRINT(Title, Type, Value, Location) \
1211do { \
1212 if (yydebug) \
1213 { \
1214 YYFPRINTF (stderr, "%s ", Title); \
1215 yy_symbol_print (stderr, \
1216 Type, Value); \
1217 YYFPRINTF (stderr, "\n"); \
1218 } \
1219} while (0)
1220
1221
1222/*----------------------------------------.
1223| Print this symbol's value on YYOUTPUT. |
1224`----------------------------------------*/
1225
1226static void
1227yy_symbol_value_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep)
1228{
1229 FILE *yyo = yyoutput;
1230 YYUSE (yyo);
1231 if (!yyvaluep)
1232 return;
1233# ifdef YYPRINT
1234 if (yytype < YYNTOKENS)
1235 YYPRINT (yyoutput, yytoknum[yytype], *yyvaluep);
1236# endif
1237 YYUSE (yytype);
1238}
1239
1240
1241/*--------------------------------.
1242| Print this symbol on YYOUTPUT. |
1243`--------------------------------*/
1244
1245static void
1246yy_symbol_print (FILE *yyoutput, int yytype, YYSTYPE const * const yyvaluep)
1247{
1248 YYFPRINTF (yyoutput, "%s %s (",
1249 yytype < YYNTOKENS ? "token" : "nterm", yytname[yytype]);
1250
1251 yy_symbol_value_print (yyoutput, yytype, yyvaluep);
1252 YYFPRINTF (yyoutput, ")");
1253}
1254
1255/*------------------------------------------------------------------.
1256| yy_stack_print -- Print the state stack from its BOTTOM up to its |
1257| TOP (included). |
1258`------------------------------------------------------------------*/
1259
1260static void
1261yy_stack_print (yytype_int16 *yybottom, yytype_int16 *yytop)
1262{
1263 YYFPRINTF (stderr, "Stack now");
1264 for (; yybottom <= yytop; yybottom++)
1265 {
1266 int yybot = *yybottom;
1267 YYFPRINTF (stderr, " %d", yybot);
1268 }
1269 YYFPRINTF (stderr, "\n");
1270}
1271
1272# define YY_STACK_PRINT(Bottom, Top) \
1273do { \
1274 if (yydebug) \
1275 yy_stack_print ((Bottom), (Top)); \
1276} while (0)
1277
1278
1279/*------------------------------------------------.
1280| Report that the YYRULE is going to be reduced. |
1281`------------------------------------------------*/
1282
1283static void
1284yy_reduce_print (yytype_int16 *yyssp, YYSTYPE *yyvsp, int yyrule)
1285{
1286 unsigned long int yylno = yyrline[yyrule];
1287 int yynrhs = yyr2[yyrule];
1288 int yyi;
1289 YYFPRINTF (stderr, "Reducing stack by rule %d (line %lu):\n",
1290 yyrule - 1, yylno);
1291 /* The symbols being reduced. */
1292 for (yyi = 0; yyi < yynrhs; yyi++)
1293 {
1294 YYFPRINTF (stderr, " $%d = ", yyi + 1);
1295 yy_symbol_print (stderr,
1296 yystos[yyssp[yyi + 1 - yynrhs]],
1297 &(yyvsp[(yyi + 1) - (yynrhs)])
1298 );
1299 YYFPRINTF (stderr, "\n");
1300 }
1301}
1302
1303# define YY_REDUCE_PRINT(Rule) \
1304do { \
1305 if (yydebug) \
1306 yy_reduce_print (yyssp, yyvsp, Rule); \
1307} while (0)
1308
1309/* Nonzero means print parse trace. It is left uninitialized so that
1310 multiple parsers can coexist. */
1311int yydebug;
1312#else /* !YYDEBUG */
1313# define YYDPRINTF(Args)
1314# define YY_SYMBOL_PRINT(Title, Type, Value, Location)
1315# define YY_STACK_PRINT(Bottom, Top)
1316# define YY_REDUCE_PRINT(Rule)
1317#endif /* !YYDEBUG */
1318
1319
1320/* YYINITDEPTH -- initial size of the parser's stacks. */
1321#ifndef YYINITDEPTH
1322# define YYINITDEPTH 200
1323#endif
1324
1325/* YYMAXDEPTH -- maximum size the stacks can grow to (effective only
1326 if the built-in stack extension method is used).
1327
1328 Do not make this value too large; the results are undefined if
1329 YYSTACK_ALLOC_MAXIMUM < YYSTACK_BYTES (YYMAXDEPTH)
1330 evaluated with infinite-precision integer arithmetic. */
1331
1332#ifndef YYMAXDEPTH
1333# define YYMAXDEPTH 10000
1334#endif
1335
1336
1337#if YYERROR_VERBOSE
1338
1339# ifndef yystrlen
1340# if defined __GLIBC__ && defined _STRING_H
1341# define yystrlen strlen
1342# else
1343/* Return the length of YYSTR. */
1344static YYSIZE_T
1345yystrlen (const char *yystr)
1346{
1347 YYSIZE_T yylen;
1348 for (yylen = 0; yystr[yylen]; yylen++)
1349 continue;
1350 return yylen;
1351}
1352# endif
1353# endif
1354
1355# ifndef yystpcpy
1356# if defined __GLIBC__ && defined _STRING_H && defined _GNU_SOURCE
1357# define yystpcpy stpcpy
1358# else
1359/* Copy YYSRC to YYDEST, returning the address of the terminating '\0' in
1360 YYDEST. */
1361static char *
1362yystpcpy (char *yydest, const char *yysrc)
1363{
1364 char *yyd = yydest;
1365 const char *yys = yysrc;
1366
1367 while ((*yyd++ = *yys++) != '\0')
1368 continue;
1369
1370 return yyd - 1;
1371}
1372# endif
1373# endif
1374
1375# ifndef yytnamerr
1376/* Copy to YYRES the contents of YYSTR after stripping away unnecessary
1377 quotes and backslashes, so that it's suitable for yyerror. The
1378 heuristic is that double-quoting is unnecessary unless the string
1379 contains an apostrophe, a comma, or backslash (other than
1380 backslash-backslash). YYSTR is taken from yytname. If YYRES is
1381 null, do not copy; instead, return the length of what the result
1382 would have been. */
1383static YYSIZE_T
1384yytnamerr (char *yyres, const char *yystr)
1385{
1386 if (*yystr == '"')
1387 {
1388 YYSIZE_T yyn = 0;
1389 char const *yyp = yystr;
1390
1391 for (;;)
1392 switch (*++yyp)
1393 {
1394 case '\'':
1395 case ',':
1396 goto do_not_strip_quotes;
1397
1398 case '\\':
1399 if (*++yyp != '\\')
1400 goto do_not_strip_quotes;
1401 /* Fall through. */
1402 default:
1403 if (yyres)
1404 yyres[yyn] = *yyp;
1405 yyn++;
1406 break;
1407
1408 case '"':
1409 if (yyres)
1410 yyres[yyn] = '\0';
1411 return yyn;
1412 }
1413 do_not_strip_quotes: ;
1414 }
1415
1416 if (! yyres)
1417 return yystrlen (yystr);
1418
1419 return yystpcpy (yyres, yystr) - yyres;
1420}
1421# endif
1422
1423/* Copy into *YYMSG, which is of size *YYMSG_ALLOC, an error message
1424 about the unexpected token YYTOKEN for the state stack whose top is
1425 YYSSP.
1426
1427 Return 0 if *YYMSG was successfully written. Return 1 if *YYMSG is
1428 not large enough to hold the message. In that case, also set
1429 *YYMSG_ALLOC to the required number of bytes. Return 2 if the
1430 required number of bytes is too large to store. */
1431static int
1432yysyntax_error (YYSIZE_T *yymsg_alloc, char **yymsg,
1433 yytype_int16 *yyssp, int yytoken)
1434{
1435 YYSIZE_T yysize0 = yytnamerr (YY_NULLPTR, yytname[yytoken]);
1436 YYSIZE_T yysize = yysize0;
1437 enum { YYERROR_VERBOSE_ARGS_MAXIMUM = 5 };
1438 /* Internationalized format string. */
1439 const char *yyformat = YY_NULLPTR;
1440 /* Arguments of yyformat. */
1441 char const *yyarg[YYERROR_VERBOSE_ARGS_MAXIMUM];
1442 /* Number of reported tokens (one for the "unexpected", one per
1443 "expected"). */
1444 int yycount = 0;
1445
1446 /* There are many possibilities here to consider:
1447 - If this state is a consistent state with a default action, then
1448 the only way this function was invoked is if the default action
1449 is an error action. In that case, don't check for expected
1450 tokens because there are none.
1451 - The only way there can be no lookahead present (in yychar) is if
1452 this state is a consistent state with a default action. Thus,
1453 detecting the absence of a lookahead is sufficient to determine
1454 that there is no unexpected or expected token to report. In that
1455 case, just report a simple "syntax error".
1456 - Don't assume there isn't a lookahead just because this state is a
1457 consistent state with a default action. There might have been a
1458 previous inconsistent state, consistent state with a non-default
1459 action, or user semantic action that manipulated yychar.
1460 - Of course, the expected token list depends on states to have
1461 correct lookahead information, and it depends on the parser not
1462 to perform extra reductions after fetching a lookahead from the
1463 scanner and before detecting a syntax error. Thus, state merging
1464 (from LALR or IELR) and default reductions corrupt the expected
1465 token list. However, the list is correct for canonical LR with
1466 one exception: it will still contain any token that will not be
1467 accepted due to an error action in a later state.
1468 */
1469 if (yytoken != YYEMPTY)
1470 {
1471 int yyn = yypact[*yyssp];
1472 yyarg[yycount++] = yytname[yytoken];
1473 if (!yypact_value_is_default (yyn))
1474 {
1475 /* Start YYX at -YYN if negative to avoid negative indexes in
1476 YYCHECK. In other words, skip the first -YYN actions for
1477 this state because they are default actions. */
1478 int yyxbegin = yyn < 0 ? -yyn : 0;
1479 /* Stay within bounds of both yycheck and yytname. */
1480 int yychecklim = YYLAST - yyn + 1;
1481 int yyxend = yychecklim < YYNTOKENS ? yychecklim : YYNTOKENS;
1482 int yyx;
1483
1484 for (yyx = yyxbegin; yyx < yyxend; ++yyx)
1485 if (yycheck[yyx + yyn] == yyx && yyx != YYTERROR
1486 && !yytable_value_is_error (yytable[yyx + yyn]))
1487 {
1488 if (yycount == YYERROR_VERBOSE_ARGS_MAXIMUM)
1489 {
1490 yycount = 1;
1491 yysize = yysize0;
1492 break;
1493 }
1494 yyarg[yycount++] = yytname[yyx];
1495 {
1496 YYSIZE_T yysize1 = yysize + yytnamerr (YY_NULLPTR, yytname[yyx]);
1497 if (! (yysize <= yysize1
1498 && yysize1 <= YYSTACK_ALLOC_MAXIMUM))
1499 return 2;
1500 yysize = yysize1;
1501 }
1502 }
1503 }
1504 }
1505
1506 switch (yycount)
1507 {
1508# define YYCASE_(N, S) \
1509 case N: \
1510 yyformat = S; \
1511 break
1512 YYCASE_(0, YY_("syntax error"));
1513 YYCASE_(1, YY_("syntax error, unexpected %s"));
1514 YYCASE_(2, YY_("syntax error, unexpected %s, expecting %s"));
1515 YYCASE_(3, YY_("syntax error, unexpected %s, expecting %s or %s"));
1516 YYCASE_(4, YY_("syntax error, unexpected %s, expecting %s or %s or %s"));
1517 YYCASE_(5, YY_("syntax error, unexpected %s, expecting %s or %s or %s or %s"));
1518# undef YYCASE_
1519 }
1520
1521 {
1522 YYSIZE_T yysize1 = yysize + yystrlen (yyformat);
1523 if (! (yysize <= yysize1 && yysize1 <= YYSTACK_ALLOC_MAXIMUM))
1524 return 2;
1525 yysize = yysize1;
1526 }
1527
1528 if (*yymsg_alloc < yysize)
1529 {
1530 *yymsg_alloc = 2 * yysize;
1531 if (! (yysize <= *yymsg_alloc
1532 && *yymsg_alloc <= YYSTACK_ALLOC_MAXIMUM))
1533 *yymsg_alloc = YYSTACK_ALLOC_MAXIMUM;
1534 return 1;
1535 }
1536
1537 /* Avoid sprintf, as that infringes on the user's name space.
1538 Don't have undefined behavior even if the translation
1539 produced a string with the wrong number of "%s"s. */
1540 {
1541 char *yyp = *yymsg;
1542 int yyi = 0;
1543 while ((*yyp = *yyformat) != '\0')
1544 if (*yyp == '%' && yyformat[1] == 's' && yyi < yycount)
1545 {
1546 yyp += yytnamerr (yyp, yyarg[yyi++]);
1547 yyformat += 2;
1548 }
1549 else
1550 {
1551 yyp++;
1552 yyformat++;
1553 }
1554 }
1555 return 0;
1556}
1557#endif /* YYERROR_VERBOSE */
1558
1559/*-----------------------------------------------.
1560| Release the memory associated to this symbol. |
1561`-----------------------------------------------*/
1562
1563static void
1564yydestruct (const char *yymsg, int yytype, YYSTYPE *yyvaluep)
1565{
1566 YYUSE (yyvaluep);
1567 if (!yymsg)
1568 yymsg = "Deleting";
1569 YY_SYMBOL_PRINT (yymsg, yytype, yyvaluep, yylocationp);
1570
1571 YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
1572 YYUSE (yytype);
1573 YY_IGNORE_MAYBE_UNINITIALIZED_END
1574}
1575
1576
1577
1578
1579/* The lookahead symbol. */
1580int yychar;
1581
1582/* The semantic value of the lookahead symbol. */
1583YYSTYPE yylval;
1584/* Number of syntax errors so far. */
1585int yynerrs;
1586
1587
1588/*----------.
1589| yyparse. |
1590`----------*/
1591
1592int
1593yyparse (void)
1594{
1595 int yystate;
1596 /* Number of tokens to shift before error messages enabled. */
1597 int yyerrstatus;
1598
1599 /* The stacks and their tools:
1600 'yyss': related to states.
1601 'yyvs': related to semantic values.
1602
1603 Refer to the stacks through separate pointers, to allow yyoverflow
1604 to reallocate them elsewhere. */
1605
1606 /* The state stack. */
1607 yytype_int16 yyssa[YYINITDEPTH];
1608 yytype_int16 *yyss;
1609 yytype_int16 *yyssp;
1610
1611 /* The semantic value stack. */
1612 YYSTYPE yyvsa[YYINITDEPTH];
1613 YYSTYPE *yyvs;
1614 YYSTYPE *yyvsp;
1615
1616 YYSIZE_T yystacksize;
1617
1618 int yyn;
1619 int yyresult;
1620 /* Lookahead token as an internal (translated) token number. */
1621 int yytoken = 0;
1622 /* The variables used to return semantic value and location from the
1623 action routines. */
1624 YYSTYPE yyval;
1625
1626#if YYERROR_VERBOSE
1627 /* Buffer for error messages, and its allocated size. */
1628 char yymsgbuf[128];
1629 char *yymsg = yymsgbuf;
1630 YYSIZE_T yymsg_alloc = sizeof yymsgbuf;
1631#endif
1632
1633#define YYPOPSTACK(N) (yyvsp -= (N), yyssp -= (N))
1634
1635 /* The number of symbols on the RHS of the reduced rule.
1636 Keep to zero when no symbol should be popped. */
1637 int yylen = 0;
1638
1639 yyssp = yyss = yyssa;
1640 yyvsp = yyvs = yyvsa;
1641 yystacksize = YYINITDEPTH;
1642
1643 YYDPRINTF ((stderr, "Starting parse\n"));
1644
1645 yystate = 0;
1646 yyerrstatus = 0;
1647 yynerrs = 0;
1648 yychar = YYEMPTY; /* Cause a token to be read. */
1649 goto yysetstate;
1650
1651/*------------------------------------------------------------.
1652| yynewstate -- Push a new state, which is found in yystate. |
1653`------------------------------------------------------------*/
1654 yynewstate:
1655 /* In all cases, when you get here, the value and location stacks
1656 have just been pushed. So pushing a state here evens the stacks. */
1657 yyssp++;
1658
1659 yysetstate:
1660 *yyssp = yystate;
1661
1662 if (yyss + yystacksize - 1 <= yyssp)
1663 {
1664 /* Get the current used size of the three stacks, in elements. */
1665 YYSIZE_T yysize = yyssp - yyss + 1;
1666
1667#ifdef yyoverflow
1668 {
1669 /* Give user a chance to reallocate the stack. Use copies of
1670 these so that the &'s don't force the real ones into
1671 memory. */
1672 YYSTYPE *yyvs1 = yyvs;
1673 yytype_int16 *yyss1 = yyss;
1674
1675 /* Each stack pointer address is followed by the size of the
1676 data in use in that stack, in bytes. This used to be a
1677 conditional around just the two extra args, but that might
1678 be undefined if yyoverflow is a macro. */
1679 yyoverflow (YY_("memory exhausted"),
1680 &yyss1, yysize * sizeof (*yyssp),
1681 &yyvs1, yysize * sizeof (*yyvsp),
1682 &yystacksize);
1683
1684 yyss = yyss1;
1685 yyvs = yyvs1;
1686 }
1687#else /* no yyoverflow */
1688# ifndef YYSTACK_RELOCATE
1689 goto yyexhaustedlab;
1690# else
1691 /* Extend the stack our own way. */
1692 if (YYMAXDEPTH <= yystacksize)
1693 goto yyexhaustedlab;
1694 yystacksize *= 2;
1695 if (YYMAXDEPTH < yystacksize)
1696 yystacksize = YYMAXDEPTH;
1697
1698 {
1699 yytype_int16 *yyss1 = yyss;
1700 union yyalloc *yyptr =
1701 (union yyalloc *) YYSTACK_ALLOC (YYSTACK_BYTES (yystacksize));
1702 if (! yyptr)
1703 goto yyexhaustedlab;
1704 YYSTACK_RELOCATE (yyss_alloc, yyss);
1705 YYSTACK_RELOCATE (yyvs_alloc, yyvs);
1706# undef YYSTACK_RELOCATE
1707 if (yyss1 != yyssa)
1708 YYSTACK_FREE (yyss1);
1709 }
1710# endif
1711#endif /* no yyoverflow */
1712
1713 yyssp = yyss + yysize - 1;
1714 yyvsp = yyvs + yysize - 1;
1715
1716 YYDPRINTF ((stderr, "Stack size increased to %lu\n",
1717 (unsigned long int) yystacksize));
1718
1719 if (yyss + yystacksize - 1 <= yyssp)
1720 YYABORT;
1721 }
1722
1723 YYDPRINTF ((stderr, "Entering state %d\n", yystate));
1724
1725 if (yystate == YYFINAL)
1726 YYACCEPT;
1727
1728 goto yybackup;
1729
1730/*-----------.
1731| yybackup. |
1732`-----------*/
1733yybackup:
1734
1735 /* Do appropriate processing given the current state. Read a
1736 lookahead token if we need one and don't already have one. */
1737
1738 /* First try to decide what to do without reference to lookahead token. */
1739 yyn = yypact[yystate];
1740 if (yypact_value_is_default (yyn))
1741 goto yydefault;
1742
1743 /* Not known => get a lookahead token if don't already have one. */
1744
1745 /* YYCHAR is either YYEMPTY or YYEOF or a valid lookahead symbol. */
1746 if (yychar == YYEMPTY)
1747 {
1748 YYDPRINTF ((stderr, "Reading a token: "));
1749 yychar = yylex ();
1750 }
1751
1752 if (yychar <= YYEOF)
1753 {
1754 yychar = yytoken = YYEOF;
1755 YYDPRINTF ((stderr, "Now at end of input.\n"));
1756 }
1757 else
1758 {
1759 yytoken = YYTRANSLATE (yychar);
1760 YY_SYMBOL_PRINT ("Next token is", yytoken, &yylval, &yylloc);
1761 }
1762
1763 /* If the proper action on seeing token YYTOKEN is to reduce or to
1764 detect an error, take that action. */
1765 yyn += yytoken;
1766 if (yyn < 0 || YYLAST < yyn || yycheck[yyn] != yytoken)
1767 goto yydefault;
1768 yyn = yytable[yyn];
1769 if (yyn <= 0)
1770 {
1771 if (yytable_value_is_error (yyn))
1772 goto yyerrlab;
1773 yyn = -yyn;
1774 goto yyreduce;
1775 }
1776
1777 /* Count tokens shifted since error; after three, turn off error
1778 status. */
1779 if (yyerrstatus)
1780 yyerrstatus--;
1781
1782 /* Shift the lookahead token. */
1783 YY_SYMBOL_PRINT ("Shifting", yytoken, &yylval, &yylloc);
1784
1785 /* Discard the shifted token. */
1786 yychar = YYEMPTY;
1787
1788 yystate = yyn;
1789 YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
1790 *++yyvsp = yylval;
1791 YY_IGNORE_MAYBE_UNINITIALIZED_END
1792
1793 goto yynewstate;
1794
1795
1796/*-----------------------------------------------------------.
1797| yydefault -- do the default action for the current state. |
1798`-----------------------------------------------------------*/
1799yydefault:
1800 yyn = yydefact[yystate];
1801 if (yyn == 0)
1802 goto yyerrlab;
1803 goto yyreduce;
1804
1805
1806/*-----------------------------.
1807| yyreduce -- Do a reduction. |
1808`-----------------------------*/
1809yyreduce:
1810 /* yyn is the number of a rule to reduce with. */
1811 yylen = yyr2[yyn];
1812
1813 /* If YYLEN is nonzero, implement the default value of the action:
1814 '$$ = $1'.
1815
1816 Otherwise, the following line sets YYVAL to garbage.
1817 This behavior is undocumented and Bison
1818 users should not rely upon it. Assigning to YYVAL
1819 unconditionally makes the parser a bit smaller, and it avoids a
1820 GCC warning that YYVAL may be used uninitialized. */
1821 yyval = yyvsp[1-yylen];
1822
1823
1824 YY_REDUCE_PRINT (yyn);
1825 switch (yyn)
1826 {
1827 case 2:
1828#line 182 "chuck.y" /* yacc.c:1646 */
1829 { (yyval.program) = g_program = new_program( (yyvsp[0].program_section), EM_lineNum ); }
1830#line 1831 "chuck.tab.c" /* yacc.c:1646 */
1831 break;
1832
1833 case 3:
1834#line 183 "chuck.y" /* yacc.c:1646 */
1835 { (yyval.program) = g_program = prepend_program( (yyvsp[-1].program_section), (yyvsp[0].program), EM_lineNum ); }
1836#line 1837 "chuck.tab.c" /* yacc.c:1646 */
1837 break;
1838
1839 case 4:
1840#line 187 "chuck.y" /* yacc.c:1646 */
1841 { (yyval.program_section) = new_section_stmt( (yyvsp[0].stmt_list), EM_lineNum ); }
1842#line 1843 "chuck.tab.c" /* yacc.c:1646 */
1843 break;
1844
1845 case 5:
1846#line 188 "chuck.y" /* yacc.c:1646 */
1847 { (yyval.program_section) = new_section_func_def( (yyvsp[0].func_def), EM_lineNum ); }
1848#line 1849 "chuck.tab.c" /* yacc.c:1646 */
1849 break;
1850
1851 case 6:
1852#line 189 "chuck.y" /* yacc.c:1646 */
1853 { (yyval.program_section) = new_section_class_def( (yyvsp[0].class_def), EM_lineNum ); }
1854#line 1855 "chuck.tab.c" /* yacc.c:1646 */
1855 break;
1856
1857 case 7:
1858#line 194 "chuck.y" /* yacc.c:1646 */
1859 { (yyval.class_def) = new_class_def( (yyvsp[-5].ival), (yyvsp[-3].id_list), NULL, (yyvsp[-1].class_body), EM_lineNum ); }
1860#line 1861 "chuck.tab.c" /* yacc.c:1646 */
1861 break;
1862
1863 case 8:
1864#line 196 "chuck.y" /* yacc.c:1646 */
1865 { (yyval.class_def) = new_class_def( (yyvsp[-6].ival), (yyvsp[-4].id_list), (yyvsp[-3].class_ext), (yyvsp[-1].class_body), EM_lineNum ); }
1866#line 1867 "chuck.tab.c" /* yacc.c:1646 */
1867 break;
1868
1869 case 9:
1870#line 198 "chuck.y" /* yacc.c:1646 */
1871 { (yyval.class_def) = new_iface_def( (yyvsp[-5].ival), (yyvsp[-3].id_list), NULL, (yyvsp[-1].class_body), EM_lineNum ); }
1872#line 1873 "chuck.tab.c" /* yacc.c:1646 */
1873 break;
1874
1875 case 10:
1876#line 200 "chuck.y" /* yacc.c:1646 */
1877 { (yyval.class_def) = new_iface_def( (yyvsp[-6].ival), (yyvsp[-4].id_list), (yyvsp[-3].class_ext), (yyvsp[-1].class_body), EM_lineNum ); }
1878#line 1879 "chuck.tab.c" /* yacc.c:1646 */
1879 break;
1880
1881 case 11:
1882#line 204 "chuck.y" /* yacc.c:1646 */
1883 { (yyval.class_ext) = new_class_ext( NULL, (yyvsp[0].id_list), EM_lineNum ); }
1884#line 1885 "chuck.tab.c" /* yacc.c:1646 */
1885 break;
1886
1887 case 12:
1888#line 205 "chuck.y" /* yacc.c:1646 */
1889 { (yyval.class_ext) = new_class_ext( (yyvsp[0].id_list), (yyvsp[-2].id_list), EM_lineNum ); }
1890#line 1891 "chuck.tab.c" /* yacc.c:1646 */
1891 break;
1892
1893 case 13:
1894#line 206 "chuck.y" /* yacc.c:1646 */
1895 { (yyval.class_ext) = new_class_ext( (yyvsp[0].id_list), NULL, EM_lineNum ); }
1896#line 1897 "chuck.tab.c" /* yacc.c:1646 */
1897 break;
1898
1899 case 14:
1900#line 207 "chuck.y" /* yacc.c:1646 */
1901 { (yyval.class_ext) = new_class_ext( (yyvsp[-2].id_list), (yyvsp[0].id_list), EM_lineNum ); }
1902#line 1903 "chuck.tab.c" /* yacc.c:1646 */
1903 break;
1904
1905 case 15:
1906#line 211 "chuck.y" /* yacc.c:1646 */
1907 { (yyval.class_body) = (yyvsp[0].class_body); }
1908#line 1909 "chuck.tab.c" /* yacc.c:1646 */
1909 break;
1910
1911 case 16:
1912#line 212 "chuck.y" /* yacc.c:1646 */
1913 { (yyval.class_body) = NULL; }
1914#line 1915 "chuck.tab.c" /* yacc.c:1646 */
1915 break;
1916
1917 case 17:
1918#line 216 "chuck.y" /* yacc.c:1646 */
1919 { (yyval.class_body) = new_class_body( (yyvsp[0].program_section), EM_lineNum ); }
1920#line 1921 "chuck.tab.c" /* yacc.c:1646 */
1921 break;
1922
1923 case 18:
1924#line 217 "chuck.y" /* yacc.c:1646 */
1925 { (yyval.class_body) = prepend_class_body( (yyvsp[-1].program_section), (yyvsp[0].class_body), EM_lineNum ); }
1926#line 1927 "chuck.tab.c" /* yacc.c:1646 */
1927 break;
1928
1929 case 19:
1930#line 222 "chuck.y" /* yacc.c:1646 */
1931 { (yyval.program_section) = new_section_stmt( (yyvsp[0].stmt_list), EM_lineNum ); }
1932#line 1933 "chuck.tab.c" /* yacc.c:1646 */
1933 break;
1934
1935 case 20:
1936#line 223 "chuck.y" /* yacc.c:1646 */
1937 { (yyval.program_section) = new_section_func_def( (yyvsp[0].func_def), EM_lineNum ); }
1938#line 1939 "chuck.tab.c" /* yacc.c:1646 */
1939 break;
1940
1941 case 21:
1942#line 224 "chuck.y" /* yacc.c:1646 */
1943 { (yyval.program_section) = new_section_class_def( (yyvsp[0].class_def), EM_lineNum ); }
1944#line 1945 "chuck.tab.c" /* yacc.c:1646 */
1945 break;
1946
1947 case 22:
1948#line 228 "chuck.y" /* yacc.c:1646 */
1949 { (yyval.class_ext) = new_class_ext( NULL, (yyvsp[0].id_list), EM_lineNum ); }
1950#line 1951 "chuck.tab.c" /* yacc.c:1646 */
1951 break;
1952
1953 case 23:
1954#line 232 "chuck.y" /* yacc.c:1646 */
1955 { (yyval.id_list) = new_id_list( (yyvsp[0].sval), EM_lineNum ); }
1956#line 1957 "chuck.tab.c" /* yacc.c:1646 */
1957 break;
1958
1959 case 24:
1960#line 233 "chuck.y" /* yacc.c:1646 */
1961 { (yyval.id_list) = prepend_id_list( (yyvsp[-2].sval), (yyvsp[0].id_list), EM_lineNum ); }
1962#line 1963 "chuck.tab.c" /* yacc.c:1646 */
1963 break;
1964
1965 case 25:
1966#line 237 "chuck.y" /* yacc.c:1646 */
1967 { (yyval.id_list) = new_id_list( (yyvsp[0].sval), EM_lineNum ); }
1968#line 1969 "chuck.tab.c" /* yacc.c:1646 */
1969 break;
1970
1971 case 26:
1972#line 238 "chuck.y" /* yacc.c:1646 */
1973 { (yyval.id_list) = prepend_id_list( (yyvsp[-2].sval), (yyvsp[0].id_list), EM_lineNum ); }
1974#line 1975 "chuck.tab.c" /* yacc.c:1646 */
1975 break;
1976
1977 case 27:
1978#line 243 "chuck.y" /* yacc.c:1646 */
1979 { (yyval.func_def) = new_func_def( (yyvsp[-7].ival), (yyvsp[-6].ival), (yyvsp[-5].type_decl), (yyvsp[-4].sval), (yyvsp[-2].arg_list), (yyvsp[0].stmt), EM_lineNum ); }
1980#line 1981 "chuck.tab.c" /* yacc.c:1646 */
1981 break;
1982
1983 case 28:
1984#line 245 "chuck.y" /* yacc.c:1646 */
1985 { (yyval.func_def) = new_func_def( (yyvsp[-6].ival), (yyvsp[-5].ival), (yyvsp[-4].type_decl), (yyvsp[-3].sval), NULL, (yyvsp[0].stmt), EM_lineNum ); }
1986#line 1987 "chuck.tab.c" /* yacc.c:1646 */
1987 break;
1988
1989 case 29:
1990#line 247 "chuck.y" /* yacc.c:1646 */
1991 { (yyval.func_def) = new_func_def( (yyvsp[-7].ival), (yyvsp[-6].ival), (yyvsp[-5].type_decl), (yyvsp[-4].sval), (yyvsp[-2].arg_list), NULL, EM_lineNum ); }
1992#line 1993 "chuck.tab.c" /* yacc.c:1646 */
1993 break;
1994
1995 case 30:
1996#line 249 "chuck.y" /* yacc.c:1646 */
1997 { (yyval.func_def) = new_func_def( (yyvsp[-6].ival), (yyvsp[-5].ival), (yyvsp[-4].type_decl), (yyvsp[-3].sval), NULL, NULL, EM_lineNum ); }
1998#line 1999 "chuck.tab.c" /* yacc.c:1646 */
1999 break;
2000
2001 case 31:
2002#line 253 "chuck.y" /* yacc.c:1646 */
2003 { (yyval.ival) = ae_key_public; }
2004#line 2005 "chuck.tab.c" /* yacc.c:1646 */
2005 break;
2006
2007 case 32:
2008#line 254 "chuck.y" /* yacc.c:1646 */
2009 { (yyval.ival) = ae_key_private; }
2010#line 2011 "chuck.tab.c" /* yacc.c:1646 */
2011 break;
2012
2013 case 33:
2014#line 255 "chuck.y" /* yacc.c:1646 */
2015 { (yyval.ival) = ae_key_private; }
2016#line 2017 "chuck.tab.c" /* yacc.c:1646 */
2017 break;
2018
2019 case 34:
2020#line 259 "chuck.y" /* yacc.c:1646 */
2021 { (yyval.ival) = ae_key_func; }
2022#line 2023 "chuck.tab.c" /* yacc.c:1646 */
2023 break;
2024
2025 case 35:
2026#line 260 "chuck.y" /* yacc.c:1646 */
2027 { (yyval.ival) = ae_key_public; }
2028#line 2029 "chuck.tab.c" /* yacc.c:1646 */
2029 break;
2030
2031 case 36:
2032#line 261 "chuck.y" /* yacc.c:1646 */
2033 { (yyval.ival) = ae_key_protected; }
2034#line 2035 "chuck.tab.c" /* yacc.c:1646 */
2035 break;
2036
2037 case 37:
2038#line 262 "chuck.y" /* yacc.c:1646 */
2039 { (yyval.ival) = ae_key_private; }
2040#line 2041 "chuck.tab.c" /* yacc.c:1646 */
2041 break;
2042
2043 case 38:
2044#line 266 "chuck.y" /* yacc.c:1646 */
2045 { (yyval.ival) = ae_key_static; }
2046#line 2047 "chuck.tab.c" /* yacc.c:1646 */
2047 break;
2048
2049 case 39:
2050#line 267 "chuck.y" /* yacc.c:1646 */
2051 { (yyval.ival) = ae_key_abstract; }
2052#line 2053 "chuck.tab.c" /* yacc.c:1646 */
2053 break;
2054
2055 case 40:
2056#line 268 "chuck.y" /* yacc.c:1646 */
2057 { (yyval.ival) = ae_key_instance; }
2058#line 2059 "chuck.tab.c" /* yacc.c:1646 */
2059 break;
2060
2061 case 41:
2062#line 272 "chuck.y" /* yacc.c:1646 */
2063 { (yyval.type_decl) = new_type_decl( new_id_list( (yyvsp[0].sval), EM_lineNum ), 0, EM_lineNum ); }
2064#line 2065 "chuck.tab.c" /* yacc.c:1646 */
2065 break;
2066
2067 case 42:
2068#line 273 "chuck.y" /* yacc.c:1646 */
2069 { (yyval.type_decl) = new_type_decl( new_id_list( (yyvsp[-1].sval), EM_lineNum ), 1, EM_lineNum ); }
2070#line 2071 "chuck.tab.c" /* yacc.c:1646 */
2071 break;
2072
2073 case 43:
2074#line 277 "chuck.y" /* yacc.c:1646 */
2075 { (yyval.type_decl) = new_type_decl( (yyvsp[-1].id_list), 0, EM_lineNum ); }
2076#line 2077 "chuck.tab.c" /* yacc.c:1646 */
2077 break;
2078
2079 case 44:
2080#line 278 "chuck.y" /* yacc.c:1646 */
2081 { (yyval.type_decl) = new_type_decl( (yyvsp[-2].id_list), 1, EM_lineNum ); }
2082#line 2083 "chuck.tab.c" /* yacc.c:1646 */
2083 break;
2084
2085 case 45:
2086#line 287 "chuck.y" /* yacc.c:1646 */
2087 { (yyval.type_decl) = (yyvsp[0].type_decl); }
2088#line 2089 "chuck.tab.c" /* yacc.c:1646 */
2089 break;
2090
2091 case 46:
2092#line 288 "chuck.y" /* yacc.c:1646 */
2093 { (yyval.type_decl) = (yyvsp[0].type_decl); }
2094#line 2095 "chuck.tab.c" /* yacc.c:1646 */
2095 break;
2096
2097 case 47:
2098#line 293 "chuck.y" /* yacc.c:1646 */
2099 { (yyval.type_decl) = (yyvsp[0].type_decl); }
2100#line 2101 "chuck.tab.c" /* yacc.c:1646 */
2101 break;
2102
2103 case 48:
2104#line 294 "chuck.y" /* yacc.c:1646 */
2105 { (yyval.type_decl) = add_type_decl_array( (yyvsp[-1].type_decl), (yyvsp[0].array_sub), EM_lineNum ); }
2106#line 2107 "chuck.tab.c" /* yacc.c:1646 */
2107 break;
2108
2109 case 49:
2110#line 298 "chuck.y" /* yacc.c:1646 */
2111 { (yyval.arg_list) = new_arg_list( (yyvsp[-1].type_decl), (yyvsp[0].var_decl), EM_lineNum ); }
2112#line 2113 "chuck.tab.c" /* yacc.c:1646 */
2113 break;
2114
2115 case 50:
2116#line 299 "chuck.y" /* yacc.c:1646 */
2117 { (yyval.arg_list) = prepend_arg_list( (yyvsp[-3].type_decl), (yyvsp[-2].var_decl), (yyvsp[0].arg_list), EM_lineNum ); }
2118#line 2119 "chuck.tab.c" /* yacc.c:1646 */
2119 break;
2120
2121 case 51:
2122#line 303 "chuck.y" /* yacc.c:1646 */
2123 { (yyval.stmt_list) = new_stmt_list( (yyvsp[0].stmt), EM_lineNum ); }
2124#line 2125 "chuck.tab.c" /* yacc.c:1646 */
2125 break;
2126
2127 case 52:
2128#line 304 "chuck.y" /* yacc.c:1646 */
2129 { (yyval.stmt_list) = prepend_stmt_list( (yyvsp[-1].stmt), (yyvsp[0].stmt_list), EM_lineNum ); }
2130#line 2131 "chuck.tab.c" /* yacc.c:1646 */
2131 break;
2132
2133 case 53:
2134#line 308 "chuck.y" /* yacc.c:1646 */
2135 { (yyval.stmt) = (yyvsp[0].stmt); }
2136#line 2137 "chuck.tab.c" /* yacc.c:1646 */
2137 break;
2138
2139 case 54:
2140#line 309 "chuck.y" /* yacc.c:1646 */
2141 { (yyval.stmt) = (yyvsp[0].stmt); }
2142#line 2143 "chuck.tab.c" /* yacc.c:1646 */
2143 break;
2144
2145 case 55:
2146#line 310 "chuck.y" /* yacc.c:1646 */
2147 { (yyval.stmt) = (yyvsp[0].stmt); }
2148#line 2149 "chuck.tab.c" /* yacc.c:1646 */
2149 break;
2150
2151 case 56:
2152#line 311 "chuck.y" /* yacc.c:1646 */
2153 { (yyval.stmt) = (yyvsp[0].stmt); }
2154#line 2155 "chuck.tab.c" /* yacc.c:1646 */
2155 break;
2156
2157 case 57:
2158#line 313 "chuck.y" /* yacc.c:1646 */
2159 { (yyval.stmt) = (yyvsp[0].stmt); }
2160#line 2161 "chuck.tab.c" /* yacc.c:1646 */
2161 break;
2162
2163 case 58:
2164#line 317 "chuck.y" /* yacc.c:1646 */
2165 { (yyval.stmt) = new_stmt_from_return( NULL, EM_lineNum ); }
2166#line 2167 "chuck.tab.c" /* yacc.c:1646 */
2167 break;
2168
2169 case 59:
2170#line 318 "chuck.y" /* yacc.c:1646 */
2171 { (yyval.stmt) = new_stmt_from_return( (yyvsp[-1].exp), EM_lineNum ); }
2172#line 2173 "chuck.tab.c" /* yacc.c:1646 */
2173 break;
2174
2175 case 60:
2176#line 319 "chuck.y" /* yacc.c:1646 */
2177 { (yyval.stmt) = new_stmt_from_break( EM_lineNum ); }
2178#line 2179 "chuck.tab.c" /* yacc.c:1646 */
2179 break;
2180
2181 case 61:
2182#line 320 "chuck.y" /* yacc.c:1646 */
2183 { (yyval.stmt) = new_stmt_from_continue( EM_lineNum ); }
2184#line 2185 "chuck.tab.c" /* yacc.c:1646 */
2185 break;
2186
2187 case 62:
2188#line 325 "chuck.y" /* yacc.c:1646 */
2189 { (yyval.stmt) = new_stmt_from_if( (yyvsp[-2].exp), (yyvsp[0].stmt), NULL, EM_lineNum ); }
2190#line 2191 "chuck.tab.c" /* yacc.c:1646 */
2191 break;
2192
2193 case 63:
2194#line 327 "chuck.y" /* yacc.c:1646 */
2195 { (yyval.stmt) = new_stmt_from_if( (yyvsp[-4].exp), (yyvsp[-2].stmt), (yyvsp[0].stmt), EM_lineNum ); }
2196#line 2197 "chuck.tab.c" /* yacc.c:1646 */
2197 break;
2198
2199 case 64:
2200#line 332 "chuck.y" /* yacc.c:1646 */
2201 { (yyval.stmt) = new_stmt_from_while( (yyvsp[-2].exp), (yyvsp[0].stmt), EM_lineNum ); }
2202#line 2203 "chuck.tab.c" /* yacc.c:1646 */
2203 break;
2204
2205 case 65:
2206#line 334 "chuck.y" /* yacc.c:1646 */
2207 { (yyval.stmt) = new_stmt_from_do_while( (yyvsp[-2].exp), (yyvsp[-5].stmt), EM_lineNum ); }
2208#line 2209 "chuck.tab.c" /* yacc.c:1646 */
2209 break;
2210
2211 case 66:
2212#line 336 "chuck.y" /* yacc.c:1646 */
2213 { (yyval.stmt) = new_stmt_from_for( (yyvsp[-3].stmt), (yyvsp[-2].stmt), NULL, (yyvsp[0].stmt), EM_lineNum ); }
2214#line 2215 "chuck.tab.c" /* yacc.c:1646 */
2215 break;
2216
2217 case 67:
2218#line 338 "chuck.y" /* yacc.c:1646 */
2219 { (yyval.stmt) = new_stmt_from_for( (yyvsp[-4].stmt), (yyvsp[-3].stmt), (yyvsp[-2].exp), (yyvsp[0].stmt), EM_lineNum ); }
2220#line 2221 "chuck.tab.c" /* yacc.c:1646 */
2221 break;
2222
2223 case 68:
2224#line 340 "chuck.y" /* yacc.c:1646 */
2225 { (yyval.stmt) = new_stmt_from_until( (yyvsp[-2].exp), (yyvsp[0].stmt), EM_lineNum ); }
2226#line 2227 "chuck.tab.c" /* yacc.c:1646 */
2227 break;
2228
2229 case 69:
2230#line 342 "chuck.y" /* yacc.c:1646 */
2231 { (yyval.stmt) = new_stmt_from_do_until( (yyvsp[-2].exp), (yyvsp[-5].stmt), EM_lineNum ); }
2232#line 2233 "chuck.tab.c" /* yacc.c:1646 */
2233 break;
2234
2235 case 70:
2236#line 344 "chuck.y" /* yacc.c:1646 */
2237 { (yyval.stmt) = new_stmt_from_loop( (yyvsp[-2].exp), (yyvsp[0].stmt), EM_lineNum ); }
2238#line 2239 "chuck.tab.c" /* yacc.c:1646 */
2239 break;
2240
2241 case 71:
2242#line 348 "chuck.y" /* yacc.c:1646 */
2243 { (yyval.stmt) = new_stmt_from_code( NULL, EM_lineNum ); }
2244#line 2245 "chuck.tab.c" /* yacc.c:1646 */
2245 break;
2246
2247 case 72:
2248#line 349 "chuck.y" /* yacc.c:1646 */
2249 { (yyval.stmt) = new_stmt_from_code( (yyvsp[-1].stmt_list), EM_lineNum ); }
2250#line 2251 "chuck.tab.c" /* yacc.c:1646 */
2251 break;
2252
2253 case 73:
2254#line 353 "chuck.y" /* yacc.c:1646 */
2255 { (yyval.stmt) = NULL; }
2256#line 2257 "chuck.tab.c" /* yacc.c:1646 */
2257 break;
2258
2259 case 74:
2260#line 354 "chuck.y" /* yacc.c:1646 */
2261 { (yyval.stmt) = new_stmt_from_expression( (yyvsp[-1].exp), EM_lineNum ); }
2262#line 2263 "chuck.tab.c" /* yacc.c:1646 */
2263 break;
2264
2265 case 75:
2266#line 358 "chuck.y" /* yacc.c:1646 */
2267 { (yyval.exp) = (yyvsp[0].exp); }
2268#line 2269 "chuck.tab.c" /* yacc.c:1646 */
2269 break;
2270
2271 case 76:
2272#line 359 "chuck.y" /* yacc.c:1646 */
2273 { (yyval.exp) = prepend_expression( (yyvsp[-2].exp), (yyvsp[0].exp), EM_lineNum ); }
2274#line 2275 "chuck.tab.c" /* yacc.c:1646 */
2275 break;
2276
2277 case 77:
2278#line 363 "chuck.y" /* yacc.c:1646 */
2279 { (yyval.exp) = (yyvsp[0].exp); }
2280#line 2281 "chuck.tab.c" /* yacc.c:1646 */
2281 break;
2282
2283 case 78:
2284#line 365 "chuck.y" /* yacc.c:1646 */
2285 { (yyval.exp) = new_exp_from_binary( (yyvsp[-2].exp), (yyvsp[-1].ival), (yyvsp[0].exp), EM_lineNum ); }
2286#line 2287 "chuck.tab.c" /* yacc.c:1646 */
2287 break;
2288
2289 case 79:
2290#line 369 "chuck.y" /* yacc.c:1646 */
2291 { (yyval.exp) = (yyvsp[0].exp); }
2292#line 2293 "chuck.tab.c" /* yacc.c:1646 */
2293 break;
2294
2295 case 80:
2296#line 371 "chuck.y" /* yacc.c:1646 */
2297 { (yyval.exp) = new_exp_from_binary( (yyvsp[-2].exp), (yyvsp[-1].ival), (yyvsp[0].exp), EM_lineNum ); }
2298#line 2299 "chuck.tab.c" /* yacc.c:1646 */
2299 break;
2300
2301 case 81:
2302#line 375 "chuck.y" /* yacc.c:1646 */
2303 { (yyval.array_sub) = new_array_sub( (yyvsp[-1].exp), EM_lineNum ); }
2304#line 2305 "chuck.tab.c" /* yacc.c:1646 */
2305 break;
2306
2307 case 82:
2308#line 377 "chuck.y" /* yacc.c:1646 */
2309 { (yyval.array_sub) = prepend_array_sub( (yyvsp[0].array_sub), (yyvsp[-2].exp), EM_lineNum ); }
2310#line 2311 "chuck.tab.c" /* yacc.c:1646 */
2311 break;
2312
2313 case 83:
2314#line 381 "chuck.y" /* yacc.c:1646 */
2315 { (yyval.array_sub) = new_array_sub( NULL, EM_lineNum ); }
2316#line 2317 "chuck.tab.c" /* yacc.c:1646 */
2317 break;
2318
2319 case 84:
2320#line 382 "chuck.y" /* yacc.c:1646 */
2321 { (yyval.array_sub) = prepend_array_sub( (yyvsp[-2].array_sub), NULL, EM_lineNum ); }
2322#line 2323 "chuck.tab.c" /* yacc.c:1646 */
2323 break;
2324
2325 case 85:
2326#line 386 "chuck.y" /* yacc.c:1646 */
2327 { (yyval.exp) = (yyvsp[0].exp); }
2328#line 2329 "chuck.tab.c" /* yacc.c:1646 */
2329 break;
2330
2331 case 86:
2332#line 387 "chuck.y" /* yacc.c:1646 */
2333 { (yyval.exp) = new_exp_decl( (yyvsp[-1].type_decl), (yyvsp[0].var_decl_list), 0, EM_lineNum ); }
2334#line 2335 "chuck.tab.c" /* yacc.c:1646 */
2335 break;
2336
2337 case 87:
2338#line 388 "chuck.y" /* yacc.c:1646 */
2339 { (yyval.exp) = new_exp_decl_external( (yyvsp[-1].type_decl), (yyvsp[0].var_decl_list), 0, EM_lineNum ); }
2340#line 2341 "chuck.tab.c" /* yacc.c:1646 */
2341 break;
2342
2343 case 88:
2344#line 389 "chuck.y" /* yacc.c:1646 */
2345 { (yyval.exp) = new_exp_decl( (yyvsp[-1].type_decl), (yyvsp[0].var_decl_list), 1, EM_lineNum ); }
2346#line 2347 "chuck.tab.c" /* yacc.c:1646 */
2347 break;
2348
2349 case 89:
2350#line 390 "chuck.y" /* yacc.c:1646 */
2351 { (yyval.exp) = new_exp_decl( NULL, (yyvsp[0].var_decl_list), 0, EM_lineNum ); }
2352#line 2353 "chuck.tab.c" /* yacc.c:1646 */
2353 break;
2354
2355 case 90:
2356#line 391 "chuck.y" /* yacc.c:1646 */
2357 { (yyval.exp) = new_exp_decl( NULL, (yyvsp[0].var_decl_list), 1, EM_lineNum ); }
2358#line 2359 "chuck.tab.c" /* yacc.c:1646 */
2359 break;
2360
2361 case 91:
2362#line 395 "chuck.y" /* yacc.c:1646 */
2363 { (yyval.var_decl_list) = new_var_decl_list( (yyvsp[0].var_decl), EM_lineNum ); }
2364#line 2365 "chuck.tab.c" /* yacc.c:1646 */
2365 break;
2366
2367 case 92:
2368#line 396 "chuck.y" /* yacc.c:1646 */
2369 { (yyval.var_decl_list) = prepend_var_decl_list( (yyvsp[-2].var_decl), (yyvsp[0].var_decl_list), EM_lineNum ); }
2370#line 2371 "chuck.tab.c" /* yacc.c:1646 */
2371 break;
2372
2373 case 93:
2374#line 400 "chuck.y" /* yacc.c:1646 */
2375 { (yyval.var_decl) = new_var_decl( (yyvsp[0].sval), NULL, EM_lineNum ); }
2376#line 2377 "chuck.tab.c" /* yacc.c:1646 */
2377 break;
2378
2379 case 94:
2380#line 401 "chuck.y" /* yacc.c:1646 */
2381 { (yyval.var_decl) = new_var_decl( (yyvsp[-1].sval), (yyvsp[0].array_sub), EM_lineNum ); }
2382#line 2383 "chuck.tab.c" /* yacc.c:1646 */
2383 break;
2384
2385 case 95:
2386#line 402 "chuck.y" /* yacc.c:1646 */
2387 { (yyval.var_decl) = new_var_decl( (yyvsp[-1].sval), (yyvsp[0].array_sub), EM_lineNum ); }
2388#line 2389 "chuck.tab.c" /* yacc.c:1646 */
2389 break;
2390
2391 case 96:
2392#line 407 "chuck.y" /* yacc.c:1646 */
2393 { (yyval.complex_exp) = new_complex( (yyvsp[-1].exp), EM_lineNum ); }
2394#line 2395 "chuck.tab.c" /* yacc.c:1646 */
2395 break;
2396
2397 case 97:
2398#line 412 "chuck.y" /* yacc.c:1646 */
2399 { (yyval.polar_exp) = new_polar( (yyvsp[-1].exp), EM_lineNum ); }
2400#line 2401 "chuck.tab.c" /* yacc.c:1646 */
2401 break;
2402
2403 case 98:
2404#line 417 "chuck.y" /* yacc.c:1646 */
2405 { (yyval.vec_exp) = new_vec( (yyvsp[-1].exp), EM_lineNum ); }
2406#line 2407 "chuck.tab.c" /* yacc.c:1646 */
2407 break;
2408
2409 case 99:
2410#line 421 "chuck.y" /* yacc.c:1646 */
2411 { (yyval.ival) = ae_op_chuck; }
2412#line 2413 "chuck.tab.c" /* yacc.c:1646 */
2413 break;
2414
2415 case 100:
2416#line 422 "chuck.y" /* yacc.c:1646 */
2417 { (yyval.ival) = ae_op_at_chuck; }
2418#line 2419 "chuck.tab.c" /* yacc.c:1646 */
2419 break;
2420
2421 case 101:
2422#line 423 "chuck.y" /* yacc.c:1646 */
2423 { (yyval.ival) = ae_op_plus_chuck; }
2424#line 2425 "chuck.tab.c" /* yacc.c:1646 */
2425 break;
2426
2427 case 102:
2428#line 424 "chuck.y" /* yacc.c:1646 */
2429 { (yyval.ival) = ae_op_minus_chuck; }
2430#line 2431 "chuck.tab.c" /* yacc.c:1646 */
2431 break;
2432
2433 case 103:
2434#line 425 "chuck.y" /* yacc.c:1646 */
2435 { (yyval.ival) = ae_op_times_chuck; }
2436#line 2437 "chuck.tab.c" /* yacc.c:1646 */
2437 break;
2438
2439 case 104:
2440#line 426 "chuck.y" /* yacc.c:1646 */
2441 { (yyval.ival) = ae_op_divide_chuck; }
2442#line 2443 "chuck.tab.c" /* yacc.c:1646 */
2443 break;
2444
2445 case 105:
2446#line 427 "chuck.y" /* yacc.c:1646 */
2447 { (yyval.ival) = ae_op_shift_right_chuck; }
2448#line 2449 "chuck.tab.c" /* yacc.c:1646 */
2449 break;
2450
2451 case 106:
2452#line 428 "chuck.y" /* yacc.c:1646 */
2453 { (yyval.ival) = ae_op_shift_left_chuck; }
2454#line 2455 "chuck.tab.c" /* yacc.c:1646 */
2455 break;
2456
2457 case 107:
2458#line 429 "chuck.y" /* yacc.c:1646 */
2459 { (yyval.ival) = ae_op_percent_chuck; }
2460#line 2461 "chuck.tab.c" /* yacc.c:1646 */
2461 break;
2462
2463 case 108:
2464#line 430 "chuck.y" /* yacc.c:1646 */
2465 { (yyval.ival) = ae_op_unchuck; }
2466#line 2467 "chuck.tab.c" /* yacc.c:1646 */
2467 break;
2468
2469 case 109:
2470#line 431 "chuck.y" /* yacc.c:1646 */
2471 { (yyval.ival) = ae_op_upchuck; }
2472#line 2473 "chuck.tab.c" /* yacc.c:1646 */
2473 break;
2474
2475 case 110:
2476#line 432 "chuck.y" /* yacc.c:1646 */
2477 { (yyval.ival) = ae_op_s_and_chuck; }
2478#line 2479 "chuck.tab.c" /* yacc.c:1646 */
2479 break;
2480
2481 case 111:
2482#line 433 "chuck.y" /* yacc.c:1646 */
2483 { (yyval.ival) = ae_op_s_or_chuck; }
2484#line 2485 "chuck.tab.c" /* yacc.c:1646 */
2485 break;
2486
2487 case 112:
2488#line 434 "chuck.y" /* yacc.c:1646 */
2489 { (yyval.ival) = ae_op_s_xor_chuck; }
2490#line 2491 "chuck.tab.c" /* yacc.c:1646 */
2491 break;
2492
2493 case 113:
2494#line 438 "chuck.y" /* yacc.c:1646 */
2495 { (yyval.ival) = ae_op_arrow_left; }
2496#line 2497 "chuck.tab.c" /* yacc.c:1646 */
2497 break;
2498
2499 case 114:
2500#line 439 "chuck.y" /* yacc.c:1646 */
2501 { (yyval.ival) = ae_op_arrow_right; }
2502#line 2503 "chuck.tab.c" /* yacc.c:1646 */
2503 break;
2504
2505 case 115:
2506#line 443 "chuck.y" /* yacc.c:1646 */
2507 { (yyval.exp) = (yyvsp[0].exp); }
2508#line 2509 "chuck.tab.c" /* yacc.c:1646 */
2509 break;
2510
2511 case 116:
2512#line 445 "chuck.y" /* yacc.c:1646 */
2513 { (yyval.exp) = new_exp_from_if( (yyvsp[-4].exp), (yyvsp[-2].exp), (yyvsp[0].exp), EM_lineNum ); }
2514#line 2515 "chuck.tab.c" /* yacc.c:1646 */
2515 break;
2516
2517 case 117:
2518#line 449 "chuck.y" /* yacc.c:1646 */
2519 { (yyval.exp) = (yyvsp[0].exp); }
2520#line 2521 "chuck.tab.c" /* yacc.c:1646 */
2521 break;
2522
2523 case 118:
2524#line 451 "chuck.y" /* yacc.c:1646 */
2525 { (yyval.exp) = new_exp_from_binary( (yyvsp[-2].exp), ae_op_or, (yyvsp[0].exp), EM_lineNum ); }
2526#line 2527 "chuck.tab.c" /* yacc.c:1646 */
2527 break;
2528
2529 case 119:
2530#line 455 "chuck.y" /* yacc.c:1646 */
2531 { (yyval.exp) = (yyvsp[0].exp); }
2532#line 2533 "chuck.tab.c" /* yacc.c:1646 */
2533 break;
2534
2535 case 120:
2536#line 457 "chuck.y" /* yacc.c:1646 */
2537 { (yyval.exp) = new_exp_from_binary( (yyvsp[-2].exp), ae_op_and, (yyvsp[0].exp), EM_lineNum ); }
2538#line 2539 "chuck.tab.c" /* yacc.c:1646 */
2539 break;
2540
2541 case 121:
2542#line 461 "chuck.y" /* yacc.c:1646 */
2543 { (yyval.exp) = (yyvsp[0].exp); }
2544#line 2545 "chuck.tab.c" /* yacc.c:1646 */
2545 break;
2546
2547 case 122:
2548#line 463 "chuck.y" /* yacc.c:1646 */
2549 { (yyval.exp) = new_exp_from_binary( (yyvsp[-2].exp), ae_op_s_or, (yyvsp[0].exp), EM_lineNum ); }
2550#line 2551 "chuck.tab.c" /* yacc.c:1646 */
2551 break;
2552
2553 case 123:
2554#line 467 "chuck.y" /* yacc.c:1646 */
2555 { (yyval.exp) = (yyvsp[0].exp); }
2556#line 2557 "chuck.tab.c" /* yacc.c:1646 */
2557 break;
2558
2559 case 124:
2560#line 469 "chuck.y" /* yacc.c:1646 */
2561 { (yyval.exp) = new_exp_from_binary( (yyvsp[-2].exp), ae_op_s_xor, (yyvsp[0].exp), EM_lineNum ); }
2562#line 2563 "chuck.tab.c" /* yacc.c:1646 */
2563 break;
2564
2565 case 125:
2566#line 473 "chuck.y" /* yacc.c:1646 */
2567 { (yyval.exp) = (yyvsp[0].exp); }
2568#line 2569 "chuck.tab.c" /* yacc.c:1646 */
2569 break;
2570
2571 case 126:
2572#line 475 "chuck.y" /* yacc.c:1646 */
2573 { (yyval.exp) = new_exp_from_binary( (yyvsp[-2].exp), ae_op_s_and, (yyvsp[0].exp), EM_lineNum ); }
2574#line 2575 "chuck.tab.c" /* yacc.c:1646 */
2575 break;
2576
2577 case 127:
2578#line 479 "chuck.y" /* yacc.c:1646 */
2579 { (yyval.exp) = (yyvsp[0].exp); }
2580#line 2581 "chuck.tab.c" /* yacc.c:1646 */
2581 break;
2582
2583 case 128:
2584#line 481 "chuck.y" /* yacc.c:1646 */
2585 { (yyval.exp) = new_exp_from_binary( (yyvsp[-2].exp), ae_op_eq, (yyvsp[0].exp), EM_lineNum ); }
2586#line 2587 "chuck.tab.c" /* yacc.c:1646 */
2587 break;
2588
2589 case 129:
2590#line 483 "chuck.y" /* yacc.c:1646 */
2591 { (yyval.exp) = new_exp_from_binary( (yyvsp[-2].exp), ae_op_neq, (yyvsp[0].exp), EM_lineNum ); }
2592#line 2593 "chuck.tab.c" /* yacc.c:1646 */
2593 break;
2594
2595 case 130:
2596#line 487 "chuck.y" /* yacc.c:1646 */
2597 { (yyval.exp) = (yyvsp[0].exp); }
2598#line 2599 "chuck.tab.c" /* yacc.c:1646 */
2599 break;
2600
2601 case 131:
2602#line 489 "chuck.y" /* yacc.c:1646 */
2603 { (yyval.exp) = new_exp_from_binary( (yyvsp[-2].exp), ae_op_lt, (yyvsp[0].exp), EM_lineNum ); }
2604#line 2605 "chuck.tab.c" /* yacc.c:1646 */
2605 break;
2606
2607 case 132:
2608#line 491 "chuck.y" /* yacc.c:1646 */
2609 { (yyval.exp) = new_exp_from_binary( (yyvsp[-2].exp), ae_op_gt, (yyvsp[0].exp), EM_lineNum ); }
2610#line 2611 "chuck.tab.c" /* yacc.c:1646 */
2611 break;
2612
2613 case 133:
2614#line 493 "chuck.y" /* yacc.c:1646 */
2615 { (yyval.exp) = new_exp_from_binary( (yyvsp[-2].exp), ae_op_le, (yyvsp[0].exp), EM_lineNum ); }
2616#line 2617 "chuck.tab.c" /* yacc.c:1646 */
2617 break;
2618
2619 case 134:
2620#line 495 "chuck.y" /* yacc.c:1646 */
2621 { (yyval.exp) = new_exp_from_binary( (yyvsp[-2].exp), ae_op_ge, (yyvsp[0].exp), EM_lineNum ); }
2622#line 2623 "chuck.tab.c" /* yacc.c:1646 */
2623 break;
2624
2625 case 135:
2626#line 499 "chuck.y" /* yacc.c:1646 */
2627 { (yyval.exp) = (yyvsp[0].exp); }
2628#line 2629 "chuck.tab.c" /* yacc.c:1646 */
2629 break;
2630
2631 case 136:
2632#line 501 "chuck.y" /* yacc.c:1646 */
2633 { (yyval.exp) = new_exp_from_binary( (yyvsp[-2].exp), ae_op_shift_left, (yyvsp[0].exp), EM_lineNum ); }
2634#line 2635 "chuck.tab.c" /* yacc.c:1646 */
2635 break;
2636
2637 case 137:
2638#line 503 "chuck.y" /* yacc.c:1646 */
2639 { (yyval.exp) = new_exp_from_binary( (yyvsp[-2].exp), ae_op_shift_right, (yyvsp[0].exp), EM_lineNum ); }
2640#line 2641 "chuck.tab.c" /* yacc.c:1646 */
2641 break;
2642
2643 case 138:
2644#line 507 "chuck.y" /* yacc.c:1646 */
2645 { (yyval.exp) = (yyvsp[0].exp); }
2646#line 2647 "chuck.tab.c" /* yacc.c:1646 */
2647 break;
2648
2649 case 139:
2650#line 509 "chuck.y" /* yacc.c:1646 */
2651 { (yyval.exp) = new_exp_from_binary( (yyvsp[-2].exp), ae_op_plus, (yyvsp[0].exp), EM_lineNum ); }
2652#line 2653 "chuck.tab.c" /* yacc.c:1646 */
2653 break;
2654
2655 case 140:
2656#line 511 "chuck.y" /* yacc.c:1646 */
2657 { (yyval.exp) = new_exp_from_binary( (yyvsp[-2].exp), ae_op_minus, (yyvsp[0].exp), EM_lineNum ); }
2658#line 2659 "chuck.tab.c" /* yacc.c:1646 */
2659 break;
2660
2661 case 141:
2662#line 515 "chuck.y" /* yacc.c:1646 */
2663 { (yyval.exp) = (yyvsp[0].exp); }
2664#line 2665 "chuck.tab.c" /* yacc.c:1646 */
2665 break;
2666
2667 case 142:
2668#line 517 "chuck.y" /* yacc.c:1646 */
2669 { (yyval.exp) = new_exp_from_binary( (yyvsp[-2].exp), ae_op_times, (yyvsp[0].exp), EM_lineNum ); }
2670#line 2671 "chuck.tab.c" /* yacc.c:1646 */
2671 break;
2672
2673 case 143:
2674#line 519 "chuck.y" /* yacc.c:1646 */
2675 { (yyval.exp) = new_exp_from_binary( (yyvsp[-2].exp), ae_op_divide, (yyvsp[0].exp), EM_lineNum ); }
2676#line 2677 "chuck.tab.c" /* yacc.c:1646 */
2677 break;
2678
2679 case 144:
2680#line 521 "chuck.y" /* yacc.c:1646 */
2681 { (yyval.exp) = new_exp_from_binary( (yyvsp[-2].exp), ae_op_percent, (yyvsp[0].exp), EM_lineNum ); }
2682#line 2683 "chuck.tab.c" /* yacc.c:1646 */
2683 break;
2684
2685 case 145:
2686#line 525 "chuck.y" /* yacc.c:1646 */
2687 { (yyval.exp) = (yyvsp[0].exp); }
2688#line 2689 "chuck.tab.c" /* yacc.c:1646 */
2689 break;
2690
2691 case 146:
2692#line 527 "chuck.y" /* yacc.c:1646 */
2693 { (yyval.exp) = new_exp_from_binary( (yyvsp[-2].exp), ae_op_tilda, (yyvsp[0].exp), EM_lineNum ); }
2694#line 2695 "chuck.tab.c" /* yacc.c:1646 */
2695 break;
2696
2697 case 147:
2698#line 531 "chuck.y" /* yacc.c:1646 */
2699 { (yyval.exp) = (yyvsp[0].exp); }
2700#line 2701 "chuck.tab.c" /* yacc.c:1646 */
2701 break;
2702
2703 case 148:
2704#line 533 "chuck.y" /* yacc.c:1646 */
2705 { (yyval.exp) = new_exp_from_cast( (yyvsp[0].type_decl), (yyvsp[-2].exp), EM_lineNum ); }
2706#line 2707 "chuck.tab.c" /* yacc.c:1646 */
2707 break;
2708
2709 case 149:
2710#line 537 "chuck.y" /* yacc.c:1646 */
2711 { (yyval.exp) = (yyvsp[0].exp); }
2712#line 2713 "chuck.tab.c" /* yacc.c:1646 */
2713 break;
2714
2715 case 150:
2716#line 539 "chuck.y" /* yacc.c:1646 */
2717 { (yyval.exp) = new_exp_from_unary( ae_op_plusplus, (yyvsp[0].exp), EM_lineNum ); }
2718#line 2719 "chuck.tab.c" /* yacc.c:1646 */
2719 break;
2720
2721 case 151:
2722#line 541 "chuck.y" /* yacc.c:1646 */
2723 { (yyval.exp) = new_exp_from_unary( ae_op_minusminus, (yyvsp[0].exp), EM_lineNum ); }
2724#line 2725 "chuck.tab.c" /* yacc.c:1646 */
2725 break;
2726
2727 case 152:
2728#line 543 "chuck.y" /* yacc.c:1646 */
2729 { (yyval.exp) = new_exp_from_unary( (yyvsp[-1].ival), (yyvsp[0].exp), EM_lineNum ); }
2730#line 2731 "chuck.tab.c" /* yacc.c:1646 */
2731 break;
2732
2733 case 153:
2734#line 545 "chuck.y" /* yacc.c:1646 */
2735 { (yyval.exp) = new_exp_from_unary( ae_op_typeof, (yyvsp[0].exp), EM_lineNum ); }
2736#line 2737 "chuck.tab.c" /* yacc.c:1646 */
2737 break;
2738
2739 case 154:
2740#line 547 "chuck.y" /* yacc.c:1646 */
2741 { (yyval.exp) = new_exp_from_unary( ae_op_sizeof, (yyvsp[0].exp), EM_lineNum ); }
2742#line 2743 "chuck.tab.c" /* yacc.c:1646 */
2743 break;
2744
2745 case 155:
2746#line 549 "chuck.y" /* yacc.c:1646 */
2747 { (yyval.exp) = new_exp_from_unary2( ae_op_new, (yyvsp[0].type_decl), NULL, EM_lineNum ); }
2748#line 2749 "chuck.tab.c" /* yacc.c:1646 */
2749 break;
2750
2751 case 156:
2752#line 551 "chuck.y" /* yacc.c:1646 */
2753 { (yyval.exp) = new_exp_from_unary2( ae_op_new, (yyvsp[-1].type_decl), (yyvsp[0].array_sub), EM_lineNum ); }
2754#line 2755 "chuck.tab.c" /* yacc.c:1646 */
2755 break;
2756
2757 case 157:
2758#line 557 "chuck.y" /* yacc.c:1646 */
2759 { (yyval.ival) = ae_op_plus; }
2760#line 2761 "chuck.tab.c" /* yacc.c:1646 */
2761 break;
2762
2763 case 158:
2764#line 558 "chuck.y" /* yacc.c:1646 */
2765 { (yyval.ival) = ae_op_minus; }
2766#line 2767 "chuck.tab.c" /* yacc.c:1646 */
2767 break;
2768
2769 case 159:
2770#line 559 "chuck.y" /* yacc.c:1646 */
2771 { (yyval.ival) = ae_op_tilda; }
2772#line 2773 "chuck.tab.c" /* yacc.c:1646 */
2773 break;
2774
2775 case 160:
2776#line 560 "chuck.y" /* yacc.c:1646 */
2777 { (yyval.ival) = ae_op_exclamation; }
2778#line 2779 "chuck.tab.c" /* yacc.c:1646 */
2779 break;
2780
2781 case 161:
2782#line 561 "chuck.y" /* yacc.c:1646 */
2783 { (yyval.ival) = ae_op_times; }
2784#line 2785 "chuck.tab.c" /* yacc.c:1646 */
2785 break;
2786
2787 case 162:
2788#line 562 "chuck.y" /* yacc.c:1646 */
2789 { (yyval.ival) = ae_op_spork; }
2790#line 2791 "chuck.tab.c" /* yacc.c:1646 */
2791 break;
2792
2793 case 164:
2794#line 569 "chuck.y" /* yacc.c:1646 */
2795 { (yyval.exp) = new_exp_from_dur( (yyvsp[-2].exp), (yyvsp[0].exp), EM_lineNum ); }
2796#line 2797 "chuck.tab.c" /* yacc.c:1646 */
2797 break;
2798
2799 case 165:
2800#line 573 "chuck.y" /* yacc.c:1646 */
2801 { (yyval.exp) = (yyvsp[0].exp); }
2802#line 2803 "chuck.tab.c" /* yacc.c:1646 */
2803 break;
2804
2805 case 166:
2806#line 575 "chuck.y" /* yacc.c:1646 */
2807 { (yyval.exp) = new_exp_from_array( (yyvsp[-1].exp), (yyvsp[0].array_sub), EM_lineNum ); }
2808#line 2809 "chuck.tab.c" /* yacc.c:1646 */
2809 break;
2810
2811 case 167:
2812#line 577 "chuck.y" /* yacc.c:1646 */
2813 { (yyval.exp) = new_exp_from_func_call( (yyvsp[-2].exp), NULL, EM_lineNum ); }
2814#line 2815 "chuck.tab.c" /* yacc.c:1646 */
2815 break;
2816
2817 case 168:
2818#line 579 "chuck.y" /* yacc.c:1646 */
2819 { (yyval.exp) = new_exp_from_func_call( (yyvsp[-3].exp), (yyvsp[-1].exp), EM_lineNum ); }
2820#line 2821 "chuck.tab.c" /* yacc.c:1646 */
2821 break;
2822
2823 case 169:
2824#line 581 "chuck.y" /* yacc.c:1646 */
2825 { (yyval.exp) = new_exp_from_member_dot( (yyvsp[-2].exp), (yyvsp[0].sval), EM_lineNum ); }
2826#line 2827 "chuck.tab.c" /* yacc.c:1646 */
2827 break;
2828
2829 case 170:
2830#line 583 "chuck.y" /* yacc.c:1646 */
2831 { (yyval.exp) = new_exp_from_postfix( (yyvsp[-1].exp), ae_op_plusplus, EM_lineNum ); }
2832#line 2833 "chuck.tab.c" /* yacc.c:1646 */
2833 break;
2834
2835 case 171:
2836#line 585 "chuck.y" /* yacc.c:1646 */
2837 { (yyval.exp) = new_exp_from_postfix( (yyvsp[-1].exp), ae_op_minusminus, EM_lineNum ); }
2838#line 2839 "chuck.tab.c" /* yacc.c:1646 */
2839 break;
2840
2841 case 172:
2842#line 590 "chuck.y" /* yacc.c:1646 */
2843 { (yyval.exp) = new_exp_from_id( (yyvsp[0].sval), EM_lineNum ); }
2844#line 2845 "chuck.tab.c" /* yacc.c:1646 */
2845 break;
2846
2847 case 173:
2848#line 591 "chuck.y" /* yacc.c:1646 */
2849 { (yyval.exp) = new_exp_from_int( (yyvsp[0].ival), EM_lineNum ); }
2850#line 2851 "chuck.tab.c" /* yacc.c:1646 */
2851 break;
2852
2853 case 174:
2854#line 592 "chuck.y" /* yacc.c:1646 */
2855 { (yyval.exp) = new_exp_from_float( (yyvsp[0].fval), EM_lineNum ); }
2856#line 2857 "chuck.tab.c" /* yacc.c:1646 */
2857 break;
2858
2859 case 175:
2860#line 593 "chuck.y" /* yacc.c:1646 */
2861 { (yyval.exp) = new_exp_from_str( (yyvsp[0].sval), EM_lineNum ); }
2862#line 2863 "chuck.tab.c" /* yacc.c:1646 */
2863 break;
2864
2865 case 176:
2866#line 594 "chuck.y" /* yacc.c:1646 */
2867 { (yyval.exp) = new_exp_from_char( (yyvsp[0].sval), EM_lineNum ); }
2868#line 2869 "chuck.tab.c" /* yacc.c:1646 */
2869 break;
2870
2871 case 177:
2872#line 595 "chuck.y" /* yacc.c:1646 */
2873 { (yyval.exp) = new_exp_from_array_lit( (yyvsp[0].array_sub), EM_lineNum ); }
2874#line 2875 "chuck.tab.c" /* yacc.c:1646 */
2875 break;
2876
2877 case 178:
2878#line 596 "chuck.y" /* yacc.c:1646 */
2879 { (yyval.exp) = new_exp_from_complex( (yyvsp[0].complex_exp), EM_lineNum ); }
2880#line 2881 "chuck.tab.c" /* yacc.c:1646 */
2881 break;
2882
2883 case 179:
2884#line 597 "chuck.y" /* yacc.c:1646 */
2885 { (yyval.exp) = new_exp_from_polar( (yyvsp[0].polar_exp), EM_lineNum ); }
2886#line 2887 "chuck.tab.c" /* yacc.c:1646 */
2887 break;
2888
2889 case 180:
2890#line 598 "chuck.y" /* yacc.c:1646 */
2891 { (yyval.exp) = new_exp_from_vec( (yyvsp[0].vec_exp), EM_lineNum ); }
2892#line 2893 "chuck.tab.c" /* yacc.c:1646 */
2893 break;
2894
2895 case 181:
2896#line 599 "chuck.y" /* yacc.c:1646 */
2897 { (yyval.exp) = new_exp_from_hack( (yyvsp[-1].exp), EM_lineNum ); }
2898#line 2899 "chuck.tab.c" /* yacc.c:1646 */
2899 break;
2900
2901 case 182:
2902#line 600 "chuck.y" /* yacc.c:1646 */
2903 { (yyval.exp) = (yyvsp[-1].exp); }
2904#line 2905 "chuck.tab.c" /* yacc.c:1646 */
2905 break;
2906
2907 case 183:
2908#line 601 "chuck.y" /* yacc.c:1646 */
2909 { (yyval.exp) = new_exp_from_nil( EM_lineNum ); }
2910#line 2911 "chuck.tab.c" /* yacc.c:1646 */
2911 break;
2912
2913
2914#line 2915 "chuck.tab.c" /* yacc.c:1646 */
2915 default: break;
2916 }
2917 /* User semantic actions sometimes alter yychar, and that requires
2918 that yytoken be updated with the new translation. We take the
2919 approach of translating immediately before every use of yytoken.
2920 One alternative is translating here after every semantic action,
2921 but that translation would be missed if the semantic action invokes
2922 YYABORT, YYACCEPT, or YYERROR immediately after altering yychar or
2923 if it invokes YYBACKUP. In the case of YYABORT or YYACCEPT, an
2924 incorrect destructor might then be invoked immediately. In the
2925 case of YYERROR or YYBACKUP, subsequent parser actions might lead
2926 to an incorrect destructor call or verbose syntax error message
2927 before the lookahead is translated. */
2928 YY_SYMBOL_PRINT ("-> $$ =", yyr1[yyn], &yyval, &yyloc);
2929
2930 YYPOPSTACK (yylen);
2931 yylen = 0;
2932 YY_STACK_PRINT (yyss, yyssp);
2933
2934 *++yyvsp = yyval;
2935
2936 /* Now 'shift' the result of the reduction. Determine what state
2937 that goes to, based on the state we popped back to and the rule
2938 number reduced by. */
2939
2940 yyn = yyr1[yyn];
2941
2942 yystate = yypgoto[yyn - YYNTOKENS] + *yyssp;
2943 if (0 <= yystate && yystate <= YYLAST && yycheck[yystate] == *yyssp)
2944 yystate = yytable[yystate];
2945 else
2946 yystate = yydefgoto[yyn - YYNTOKENS];
2947
2948 goto yynewstate;
2949
2950
2951/*--------------------------------------.
2952| yyerrlab -- here on detecting error. |
2953`--------------------------------------*/
2954yyerrlab:
2955 /* Make sure we have latest lookahead translation. See comments at
2956 user semantic actions for why this is necessary. */
2957 yytoken = yychar == YYEMPTY ? YYEMPTY : YYTRANSLATE (yychar);
2958
2959 /* If not already recovering from an error, report this error. */
2960 if (!yyerrstatus)
2961 {
2962 ++yynerrs;
2963#if ! YYERROR_VERBOSE
2964 yyerror (YY_("syntax error"));
2965#else
2966# define YYSYNTAX_ERROR yysyntax_error (&yymsg_alloc, &yymsg, \
2967 yyssp, yytoken)
2968 {
2969 char const *yymsgp = YY_("syntax error");
2970 int yysyntax_error_status;
2971 yysyntax_error_status = YYSYNTAX_ERROR;
2972 if (yysyntax_error_status == 0)
2973 yymsgp = yymsg;
2974 else if (yysyntax_error_status == 1)
2975 {
2976 if (yymsg != yymsgbuf)
2977 YYSTACK_FREE (yymsg);
2978 yymsg = (char *) YYSTACK_ALLOC (yymsg_alloc);
2979 if (!yymsg)
2980 {
2981 yymsg = yymsgbuf;
2982 yymsg_alloc = sizeof yymsgbuf;
2983 yysyntax_error_status = 2;
2984 }
2985 else
2986 {
2987 yysyntax_error_status = YYSYNTAX_ERROR;
2988 yymsgp = yymsg;
2989 }
2990 }
2991 yyerror (yymsgp);
2992 if (yysyntax_error_status == 2)
2993 goto yyexhaustedlab;
2994 }
2995# undef YYSYNTAX_ERROR
2996#endif
2997 }
2998
2999
3000
3001 if (yyerrstatus == 3)
3002 {
3003 /* If just tried and failed to reuse lookahead token after an
3004 error, discard it. */
3005
3006 if (yychar <= YYEOF)
3007 {
3008 /* Return failure if at end of input. */
3009 if (yychar == YYEOF)
3010 YYABORT;
3011 }
3012 else
3013 {
3014 yydestruct ("Error: discarding",
3015 yytoken, &yylval);
3016 yychar = YYEMPTY;
3017 }
3018 }
3019
3020 /* Else will try to reuse lookahead token after shifting the error
3021 token. */
3022 goto yyerrlab1;
3023
3024
3025/*---------------------------------------------------.
3026| yyerrorlab -- error raised explicitly by YYERROR. |
3027`---------------------------------------------------*/
3028yyerrorlab:
3029
3030 /* Pacify compilers like GCC when the user code never invokes
3031 YYERROR and the label yyerrorlab therefore never appears in user
3032 code. */
3033 if (/*CONSTCOND*/ 0)
3034 goto yyerrorlab;
3035
3036 /* Do not reclaim the symbols of the rule whose action triggered
3037 this YYERROR. */
3038 YYPOPSTACK (yylen);
3039 yylen = 0;
3040 YY_STACK_PRINT (yyss, yyssp);
3041 yystate = *yyssp;
3042 goto yyerrlab1;
3043
3044
3045/*-------------------------------------------------------------.
3046| yyerrlab1 -- common code for both syntax error and YYERROR. |
3047`-------------------------------------------------------------*/
3048yyerrlab1:
3049 yyerrstatus = 3; /* Each real token shifted decrements this. */
3050
3051 for (;;)
3052 {
3053 yyn = yypact[yystate];
3054 if (!yypact_value_is_default (yyn))
3055 {
3056 yyn += YYTERROR;
3057 if (0 <= yyn && yyn <= YYLAST && yycheck[yyn] == YYTERROR)
3058 {
3059 yyn = yytable[yyn];
3060 if (0 < yyn)
3061 break;
3062 }
3063 }
3064
3065 /* Pop the current state because it cannot handle the error token. */
3066 if (yyssp == yyss)
3067 YYABORT;
3068
3069
3070 yydestruct ("Error: popping",
3071 yystos[yystate], yyvsp);
3072 YYPOPSTACK (1);
3073 yystate = *yyssp;
3074 YY_STACK_PRINT (yyss, yyssp);
3075 }
3076
3077 YY_IGNORE_MAYBE_UNINITIALIZED_BEGIN
3078 *++yyvsp = yylval;
3079 YY_IGNORE_MAYBE_UNINITIALIZED_END
3080
3081
3082 /* Shift the error token. */
3083 YY_SYMBOL_PRINT ("Shifting", yystos[yyn], yyvsp, yylsp);
3084
3085 yystate = yyn;
3086 goto yynewstate;
3087
3088
3089/*-------------------------------------.
3090| yyacceptlab -- YYACCEPT comes here. |
3091`-------------------------------------*/
3092yyacceptlab:
3093 yyresult = 0;
3094 goto yyreturn;
3095
3096/*-----------------------------------.
3097| yyabortlab -- YYABORT comes here. |
3098`-----------------------------------*/
3099yyabortlab:
3100 yyresult = 1;
3101 goto yyreturn;
3102
3103#if !defined yyoverflow || YYERROR_VERBOSE
3104/*-------------------------------------------------.
3105| yyexhaustedlab -- memory exhaustion comes here. |
3106`-------------------------------------------------*/
3107yyexhaustedlab:
3108 yyerror (YY_("memory exhausted"));
3109 yyresult = 2;
3110 /* Fall through. */
3111#endif
3112
3113yyreturn:
3114 if (yychar != YYEMPTY)
3115 {
3116 /* Make sure we have latest lookahead translation. See comments at
3117 user semantic actions for why this is necessary. */
3118 yytoken = YYTRANSLATE (yychar);
3119 yydestruct ("Cleanup: discarding lookahead",
3120 yytoken, &yylval);
3121 }
3122 /* Do not reclaim the symbols of the rule whose action triggered
3123 this YYABORT or YYACCEPT. */
3124 YYPOPSTACK (yylen);
3125 YY_STACK_PRINT (yyss, yyssp);
3126 while (yyssp != yyss)
3127 {
3128 yydestruct ("Cleanup: popping",
3129 yystos[*yyssp], yyvsp);
3130 YYPOPSTACK (1);
3131 }
3132#ifndef yyoverflow
3133 if (yyss != yyssa)
3134 YYSTACK_FREE (yyss);
3135#endif
3136#if YYERROR_VERBOSE
3137 if (yymsg != yymsgbuf)
3138 YYSTACK_FREE (yymsg);
3139#endif
3140 return yyresult;
3141}
core/chuck.tab.h+0−203
@@ -1,203 +0,0 @@
1/* A Bison parser, made by GNU Bison 3.0.4. */
2
3/* Bison interface for Yacc-like parsers in C
4
5 Copyright (C) 1984, 1989-1990, 2000-2015 Free Software Foundation, Inc.
6
7 This program is free software: you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation, either version 3 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>. */
19
20/* As a special exception, you may create a larger work that contains
21 part or all of the Bison parser skeleton and distribute that work
22 under terms of your choice, so long as that work isn't itself a
23 parser generator using the skeleton or a modified version thereof
24 as a parser skeleton. Alternatively, if you modify or redistribute
25 the parser skeleton itself, you may (at your option) remove this
26 special exception, which will cause the skeleton and the resulting
27 Bison output files to be licensed under the GNU General Public
28 License without this special exception.
29
30 This special exception was added by the Free Software Foundation in
31 version 2.2 of Bison. */
32
33#ifndef YY_YY_CHUCK_TAB_H_INCLUDED
34# define YY_YY_CHUCK_TAB_H_INCLUDED
35/* Debug traces. */
36#ifndef YYDEBUG
37# define YYDEBUG 0
38#endif
39#if YYDEBUG
40extern int yydebug;
41#endif
42
43/* Token type. */
44#ifndef YYTOKENTYPE
45# define YYTOKENTYPE
46 enum yytokentype
47 {
48 ID = 258,
49 STRING_LIT = 259,
50 CHAR_LIT = 260,
51 NUM = 261,
52 FLOAT = 262,
53 POUND = 263,
54 COMMA = 264,
55 COLON = 265,
56 SEMICOLON = 266,
57 LPAREN = 267,
58 RPAREN = 268,
59 LBRACK = 269,
60 RBRACK = 270,
61 LBRACE = 271,
62 RBRACE = 272,
63 DOT = 273,
64 PLUS = 274,
65 MINUS = 275,
66 TIMES = 276,
67 DIVIDE = 277,
68 PERCENT = 278,
69 EQ = 279,
70 NEQ = 280,
71 LT = 281,
72 LE = 282,
73 GT = 283,
74 GE = 284,
75 AND = 285,
76 OR = 286,
77 ASSIGN = 287,
78 IF = 288,
79 THEN = 289,
80 ELSE = 290,
81 WHILE = 291,
82 FOR = 292,
83 DO = 293,
84 LOOP = 294,
85 BREAK = 295,
86 CONTINUE = 296,
87 NULL_TOK = 297,
88 FUNCTION = 298,
89 RETURN = 299,
90 QUESTION = 300,
91 EXCLAMATION = 301,
92 S_OR = 302,
93 S_AND = 303,
94 S_XOR = 304,
95 PLUSPLUS = 305,
96 MINUSMINUS = 306,
97 DOLLAR = 307,
98 POUNDPAREN = 308,
99 PERCENTPAREN = 309,
100 ATPAREN = 310,
101 SIMULT = 311,
102 PATTERN = 312,
103 CODE = 313,
104 TRANSPORT = 314,
105 HOST = 315,
106 TIME = 316,
107 WHENEVER = 317,
108 NEXT = 318,
109 UNTIL = 319,
110 EXTERNAL = 320,
111 EVERY = 321,
112 BEFORE = 322,
113 AFTER = 323,
114 AT = 324,
115 AT_SYM = 325,
116 ATAT_SYM = 326,
117 NEW = 327,
118 SIZEOF = 328,
119 TYPEOF = 329,
120 SAME = 330,
121 PLUS_CHUCK = 331,
122 MINUS_CHUCK = 332,
123 TIMES_CHUCK = 333,
124 DIVIDE_CHUCK = 334,
125 S_AND_CHUCK = 335,
126 S_OR_CHUCK = 336,
127 S_XOR_CHUCK = 337,
128 SHIFT_RIGHT_CHUCK = 338,
129 SHIFT_LEFT_CHUCK = 339,
130 PERCENT_CHUCK = 340,
131 SHIFT_RIGHT = 341,
132 SHIFT_LEFT = 342,
133 TILDA = 343,
134 CHUCK = 344,
135 COLONCOLON = 345,
136 S_CHUCK = 346,
137 AT_CHUCK = 347,
138 LEFT_S_CHUCK = 348,
139 UNCHUCK = 349,
140 UPCHUCK = 350,
141 CLASS = 351,
142 INTERFACE = 352,
143 EXTENDS = 353,
144 IMPLEMENTS = 354,
145 PUBLIC = 355,
146 PROTECTED = 356,
147 PRIVATE = 357,
148 STATIC = 358,
149 ABSTRACT = 359,
150 CONST = 360,
151 SPORK = 361,
152 ARROW_RIGHT = 362,
153 ARROW_LEFT = 363,
154 L_HACK = 364,
155 R_HACK = 365
156 };
157#endif
158
159/* Value type. */
160#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
161
162union YYSTYPE
163{
164#line 59 "chuck.y" /* yacc.c:1909 */
165
166 int pos;
167 int ival;
168 double fval;
169 c_str sval;
170
171 a_Program program;
172 a_Section program_section;
173 a_Stmt_List stmt_list;
174 a_Class_Def class_def;
175 a_Class_Ext class_ext;
176 a_Class_Body class_body;
177 a_Stmt stmt;
178 a_Exp exp;
179 a_Func_Def func_def;
180 a_Var_Decl_List var_decl_list;
181 a_Var_Decl var_decl;
182 a_Type_Decl type_decl;
183 a_Arg_List arg_list;
184 a_Id_List id_list;
185 a_Array_Sub array_sub;
186 a_Complex complex_exp;
187 a_Polar polar_exp;
188 a_Vec vec_exp; // ge: added 1.3.5.3
189
190#line 191 "chuck.tab.h" /* yacc.c:1909 */
191};
192
193typedef union YYSTYPE YYSTYPE;
194# define YYSTYPE_IS_TRIVIAL 1
195# define YYSTYPE_IS_DECLARED 1
196#endif
197
198
199extern YYSTYPE yylval;
200
201int yyparse (void);
202
203#endif /* !YY_YY_CHUCK_TAB_H_INCLUDED */
core/chuck.y+0−600
@@ -1,600 +0,0 @@
1%{
2
3/*----------------------------------------------------------------------------
4 ChucK Concurrent, On-the-fly Audio Programming Language
5 Compiler and Virtual Machine
6
7 Copyright (c) 2004 Ge Wang and Perry R. Cook. All rights reserved.
8 http://chuck.cs.princeton.edu/
9 http://soundlab.cs.princeton.edu/
10
11 This program is free software; you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation; either version 2 of the License, or
14 (at your option) any later version.
15
16 This program is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
20
21 You should have received a copy of the GNU General Public License
22 along with this program; if not, write to the Free Software
23 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
24 U.S.A.
25-----------------------------------------------------------------------------*/
26
27//-----------------------------------------------------------------------------
28// file: chuck.tab.c
29// desc: chuck parser
30//
31// author: Ge Wang (gewang@cs.princeton.edu) - generated by yacc
32// Perry R. Cook (prc@cs.princeton.edu)
33//
34// based in part on the ansi C grammar by Jeff Lee, maintained by Jutta Degener
35//
36// date: Summer 2002
37//-----------------------------------------------------------------------------
38#include <stdio.h>
39#include <string.h>
40#include <stdlib.h>
41#include "chuck_utils.h"
42#include "chuck_errmsg.h"
43#include "chuck_absyn.h"
44
45// function
46int yylex( void );
47
48void yyerror( char *s )
49{
50 EM_error( EM_tokPos, "%s", s );
51}
52
53a_Program g_program = NULL;
54
55%}
56
57
58%union
59{
60 int pos;
61 int ival;
62 double fval;
63 c_str sval;
64
65 a_Program program;
66 a_Section program_section;
67 a_Stmt_List stmt_list;
68 a_Class_Def class_def;
69 a_Class_Ext class_ext;
70 a_Class_Body class_body;
71 a_Stmt stmt;
72 a_Exp exp;
73 a_Func_Def func_def;
74 a_Var_Decl_List var_decl_list;
75 a_Var_Decl var_decl;
76 a_Type_Decl type_decl;
77 a_Arg_List arg_list;
78 a_Id_List id_list;
79 a_Array_Sub array_sub;
80 a_Complex complex_exp;
81 a_Polar polar_exp;
82 a_Vec vec_exp; // ge: added 1.3.5.3
83};
84
85// expect shift/reduce conflicts
86// 1.3.3.0: changed to 38 for char literal - spencer
87// 1.3.5.3: changed to 39 for vec literal
88%expect 39
89
90%token <sval> ID STRING_LIT CHAR_LIT
91%token <ival> NUM
92%token <fval> FLOAT
93
94%token
95 POUND COMMA COLON SEMICOLON LPAREN RPAREN
96 LBRACK RBRACK LBRACE RBRACE DOT
97 PLUS MINUS TIMES DIVIDE PERCENT
98 EQ NEQ LT LE GT GE AND OR ASSIGN
99 IF THEN ELSE WHILE FOR DO LOOP
100 BREAK CONTINUE NULL_TOK FUNCTION RETURN
101 QUESTION EXCLAMATION S_OR S_AND S_XOR
102 PLUSPLUS MINUSMINUS DOLLAR POUNDPAREN PERCENTPAREN ATPAREN
103 SIMULT PATTERN CODE TRANSPORT HOST
104 TIME WHENEVER NEXT UNTIL EVERY BEFORE
105 AFTER AT AT_SYM ATAT_SYM NEW SIZEOF TYPEOF
106 SAME PLUS_CHUCK MINUS_CHUCK TIMES_CHUCK
107 DIVIDE_CHUCK S_AND_CHUCK S_OR_CHUCK
108 S_XOR_CHUCK SHIFT_RIGHT_CHUCK
109 SHIFT_LEFT_CHUCK PERCENT_CHUCK
110 SHIFT_RIGHT SHIFT_LEFT TILDA CHUCK
111 COLONCOLON S_CHUCK AT_CHUCK LEFT_S_CHUCK
112 UNCHUCK UPCHUCK CLASS INTERFACE EXTENDS IMPLEMENTS
113 PUBLIC PROTECTED PRIVATE STATIC ABSTRACT CONST
114 SPORK ARROW_RIGHT ARROW_LEFT L_HACK R_HACK
115
116
117%type <program> program
118%type <program_section> program_section
119%type <stmt> code_segment
120%type <func_def> function_definition
121%type <class_def> class_definition
122%type <class_body> class_body
123%type <class_body> class_body2
124%type <class_ext> class_ext
125%type <ival> class_decl
126%type <class_ext> iface_ext
127%type <program_section> class_section
128%type <stmt_list> statement_list
129%type <stmt> statement
130//%type <stmt_label> label_statement
131%type <stmt> loop_statement
132%type <stmt> selection_statement
133%type <stmt> jump_statement
134%type <stmt> expression_statement
135%type <exp> expression
136%type <exp> chuck_expression
137%type <exp> arrow_expression
138%type <exp> conditional_expression
139%type <exp> logical_or_expression
140%type <exp> logical_and_expression
141%type <exp> inclusive_or_expression
142%type <exp> exclusive_or_expression
143%type <exp> and_expression
144%type <exp> equality_expression
145%type <exp> relational_expression
146%type <exp> shift_expression
147%type <exp> additive_expression
148%type <exp> multiplicative_expression
149%type <exp> tilda_expression
150%type <exp> cast_expression
151%type <exp> unary_expression
152%type <exp> dur_expression
153%type <exp> postfix_expression
154%type <exp> primary_expression
155%type <exp> decl_expression
156%type <ival> unary_operator
157%type <ival> chuck_operator
158%type <ival> arrow_operator
159%type <var_decl_list> var_decl_list
160%type <var_decl> var_decl
161%type <type_decl> type_decl_a
162%type <type_decl> type_decl_b
163%type <type_decl> type_decl
164%type <type_decl> type_decl2
165%type <ival> function_decl
166%type <ival> static_decl
167%type <arg_list> arg_list
168%type <id_list> id_list
169%type <id_list> id_dot
170%type <array_sub> array_exp
171%type <array_sub> array_empty
172%type <complex_exp> complex_exp
173%type <polar_exp> polar_exp
174%type <vec_exp> vec_exp // ge: added 1.3.5.3
175
176%start program
177
178%%
179
180program
181 : program_section { $$ = g_program = new_program( $1, EM_lineNum ); }
182 | program_section program { $$ = g_program = prepend_program( $1, $2, EM_lineNum ); }
183 ;
184
185program_section
186 : statement_list { $$ = new_section_stmt( $1, EM_lineNum ); }
187 | function_definition { $$ = new_section_func_def( $1, EM_lineNum ); }
188 | class_definition { $$ = new_section_class_def( $1, EM_lineNum ); }
189 ;
190
191class_definition
192 : class_decl CLASS id_list LBRACE class_body RBRACE
193 { $$ = new_class_def( $1, $3, NULL, $5, EM_lineNum ); }
194 | class_decl CLASS id_list class_ext LBRACE class_body RBRACE
195 { $$ = new_class_def( $1, $3, $4, $6, EM_lineNum ); }
196 | class_decl INTERFACE id_list LBRACE class_body RBRACE
197 { $$ = new_iface_def( $1, $3, NULL, $5, EM_lineNum ); }
198 | class_decl INTERFACE id_list iface_ext LBRACE class_body RBRACE
199 { $$ = new_iface_def( $1, $3, $4, $6, EM_lineNum ); }
200 ;
201
202class_ext
203 : IMPLEMENTS id_list { $$ = new_class_ext( NULL, $2, EM_lineNum ); }
204 | IMPLEMENTS id_list EXTENDS id_dot { $$ = new_class_ext( $4, $2, EM_lineNum ); }
205 | EXTENDS id_dot { $$ = new_class_ext( $2, NULL, EM_lineNum ); }
206 | EXTENDS id_dot IMPLEMENTS id_list { $$ = new_class_ext( $2, $4, EM_lineNum ); }
207 ;
208
209class_body
210 : class_body2 { $$ = $1; }
211 | { $$ = NULL; }
212 ;
213
214class_body2
215 : class_section { $$ = new_class_body( $1, EM_lineNum ); }
216 | class_section class_body2 { $$ = prepend_class_body( $1, $2, EM_lineNum ); }
217 ;
218
219
220class_section
221 : statement_list { $$ = new_section_stmt( $1, EM_lineNum ); }
222 | function_definition { $$ = new_section_func_def( $1, EM_lineNum ); }
223 | class_definition { $$ = new_section_class_def( $1, EM_lineNum ); }
224 ;
225
226iface_ext
227 : EXTENDS id_list { $$ = new_class_ext( NULL, $2, EM_lineNum ); }
228 ;
229
230id_list
231 : ID { $$ = new_id_list( $1, EM_lineNum ); }
232 | ID COMMA id_list { $$ = prepend_id_list( $1, $3, EM_lineNum ); }
233 ;
234
235id_dot
236 : ID { $$ = new_id_list( $1, EM_lineNum ); }
237 | ID DOT id_dot { $$ = prepend_id_list( $1, $3, EM_lineNum ); }
238 ;
239
240function_definition
241 : function_decl static_decl type_decl2 ID LPAREN arg_list RPAREN code_segment
242 { $$ = new_func_def( $1, $2, $3, $4, $6, $8, EM_lineNum ); }
243 | function_decl static_decl type_decl2 ID LPAREN RPAREN code_segment
244 { $$ = new_func_def( $1, $2, $3, $4, NULL, $7, EM_lineNum ); }
245 | function_decl static_decl type_decl2 ID LPAREN arg_list RPAREN SEMICOLON
246 { $$ = new_func_def( $1, $2, $3, $4, $6, NULL, EM_lineNum ); }
247 | function_decl static_decl type_decl2 ID LPAREN RPAREN SEMICOLON
248 { $$ = new_func_def( $1, $2, $3, $4, NULL, NULL, EM_lineNum ); }
249 ;
250
251class_decl
252 : PUBLIC { $$ = ae_key_public; }
253 | PRIVATE { $$ = ae_key_private; }
254 | { $$ = ae_key_private; }
255 ;
256
257function_decl
258 : FUNCTION { $$ = ae_key_func; }
259 | PUBLIC { $$ = ae_key_public; }
260 | PROTECTED { $$ = ae_key_protected; }
261 | PRIVATE { $$ = ae_key_private; }
262 ;
263
264static_decl
265 : STATIC { $$ = ae_key_static; }
266 | ABSTRACT { $$ = ae_key_abstract; }
267 | { $$ = ae_key_instance; }
268 ;
269
270type_decl_a
271 : ID { $$ = new_type_decl( new_id_list( $1, EM_lineNum ), 0, EM_lineNum ); }
272 | ID AT_SYM { $$ = new_type_decl( new_id_list( $1, EM_lineNum ), 1, EM_lineNum ); }
273 ;
274
275type_decl_b
276 : LT id_dot GT { $$ = new_type_decl( $2, 0, EM_lineNum ); }
277 | LT id_dot GT AT_SYM { $$ = new_type_decl( $2, 1, EM_lineNum ); }
278 ;
279
280//type_decl_c
281// : LPAREN id_dot RPAREN { $$ = new_type_decl( $3, 0, EM_lineNum ); }
282// // | LPAREN id_dot RPAREN AT_SYM { $$ = new_type_decl( $1, 1, EM_lineNum ); }
283// ;
284
285type_decl
286 : type_decl_a { $$ = $1; }
287 | type_decl_b { $$ = $1; }
288 // | type_decl_c { $$ = $1; }
289 ;
290
291type_decl2
292 : type_decl { $$ = $1; }
293 | type_decl array_empty { $$ = add_type_decl_array( $1, $2, EM_lineNum ); }
294 ;
295
296arg_list
297 : type_decl var_decl { $$ = new_arg_list( $1, $2, EM_lineNum ); }
298 | type_decl var_decl COMMA arg_list { $$ = prepend_arg_list( $1, $2, $4, EM_lineNum ); }
299 ;
300
301statement_list
302 : statement { $$ = new_stmt_list( $1, EM_lineNum ); }
303 | statement statement_list { $$ = prepend_stmt_list( $1, $2, EM_lineNum ); }
304 ;
305
306statement
307 : expression_statement { $$ = $1; }
308 | loop_statement { $$ = $1; }
309 | selection_statement { $$ = $1; }
310 | jump_statement { $$ = $1; }
311 // | label_statement { }
312 | code_segment { $$ = $1; }
313 ;
314
315jump_statement
316 : RETURN SEMICOLON { $$ = new_stmt_from_return( NULL, EM_lineNum ); }
317 | RETURN expression SEMICOLON { $$ = new_stmt_from_return( $2, EM_lineNum ); }
318 | BREAK SEMICOLON { $$ = new_stmt_from_break( EM_lineNum ); }
319 | CONTINUE SEMICOLON { $$ = new_stmt_from_continue( EM_lineNum ); }
320 ;
321
322selection_statement
323 : IF LPAREN expression RPAREN statement
324 { $$ = new_stmt_from_if( $3, $5, NULL, EM_lineNum ); }
325 | IF LPAREN expression RPAREN statement ELSE statement
326 { $$ = new_stmt_from_if( $3, $5, $7, EM_lineNum ); }
327 ;
328
329loop_statement
330 : WHILE LPAREN expression RPAREN statement
331 { $$ = new_stmt_from_while( $3, $5, EM_lineNum ); }
332 | DO statement WHILE LPAREN expression RPAREN SEMICOLON
333 { $$ = new_stmt_from_do_while( $5, $2, EM_lineNum ); }
334 | FOR LPAREN expression_statement expression_statement RPAREN statement
335 { $$ = new_stmt_from_for( $3, $4, NULL, $6, EM_lineNum ); }
336 | FOR LPAREN expression_statement expression_statement expression RPAREN statement
337 { $$ = new_stmt_from_for( $3, $4, $5, $7, EM_lineNum ); }
338 | UNTIL LPAREN expression RPAREN statement
339 { $$ = new_stmt_from_until( $3, $5, EM_lineNum ); }
340 | DO statement UNTIL LPAREN expression RPAREN SEMICOLON
341 { $$ = new_stmt_from_do_until( $5, $2, EM_lineNum ); }
342 | LOOP LPAREN expression RPAREN statement
343 { $$ = new_stmt_from_loop( $3, $5, EM_lineNum ); }
344 ;
345
346code_segment
347 : LBRACE RBRACE { $$ = new_stmt_from_code( NULL, EM_lineNum ); }
348 | LBRACE statement_list RBRACE { $$ = new_stmt_from_code( $2, EM_lineNum ); }
349 ;
350
351expression_statement
352 : SEMICOLON { $$ = NULL; }
353 | expression SEMICOLON { $$ = new_stmt_from_expression( $1, EM_lineNum ); }
354 ;
355
356expression
357 : chuck_expression { $$ = $1; }
358 | chuck_expression COMMA expression { $$ = prepend_expression( $1, $3, EM_lineNum ); }
359 ;
360
361chuck_expression
362 : arrow_expression { $$ = $1; }
363 | chuck_expression chuck_operator arrow_expression
364 { $$ = new_exp_from_binary( $1, $2, $3, EM_lineNum ); }
365 ;
366
367arrow_expression
368 : decl_expression { $$ = $1; }
369 | arrow_expression arrow_operator decl_expression
370 { $$ = new_exp_from_binary( $1, $2, $3, EM_lineNum ); }
371 ;
372
373array_exp
374 : LBRACK expression RBRACK { $$ = new_array_sub( $2, EM_lineNum ); }
375 | LBRACK expression RBRACK array_exp
376 { $$ = prepend_array_sub( $4, $2, EM_lineNum ); }
377 ;
378
379array_empty
380 : LBRACK RBRACK { $$ = new_array_sub( NULL, EM_lineNum ); }
381 | array_empty LBRACK RBRACK { $$ = prepend_array_sub( $1, NULL, EM_lineNum ); }
382 ;
383
384decl_expression
385 : conditional_expression { $$ = $1; }
386 | type_decl var_decl_list { $$ = new_exp_decl( $1, $2, 0, EM_lineNum ); }
387 | STATIC type_decl var_decl_list { $$ = new_exp_decl( $2, $3, 1, EM_lineNum ); }
388 | SAME var_decl_list { $$ = new_exp_decl( NULL, $2, 0, EM_lineNum ); }
389 | STATIC SAME var_decl_list { $$ = new_exp_decl( NULL, $3, 1, EM_lineNum ); }
390 ;
391
392var_decl_list
393 : var_decl { $$ = new_var_decl_list( $1, EM_lineNum ); }
394 | var_decl COMMA var_decl_list { $$ = prepend_var_decl_list( $1, $3, EM_lineNum ); }
395 ;
396
397var_decl
398 : ID { $$ = new_var_decl( $1, NULL, EM_lineNum ); }
399 | ID array_exp { $$ = new_var_decl( $1, $2, EM_lineNum ); }
400 | ID array_empty { $$ = new_var_decl( $1, $2, EM_lineNum ); }
401 ;
402
403complex_exp
404 : POUNDPAREN expression RPAREN
405 { $$ = new_complex( $2, EM_lineNum ); }
406 ;
407
408polar_exp
409 : PERCENTPAREN expression RPAREN
410 { $$ = new_polar( $2, EM_lineNum ); }
411 ;
412
413vec_exp // ge: added 1.3.5.3
414 : ATPAREN expression RPAREN
415 { $$ = new_vec( $2, EM_lineNum ); }
416 ;
417
418chuck_operator
419 : CHUCK { $$ = ae_op_chuck; }
420 | AT_CHUCK { $$ = ae_op_at_chuck; }
421 | PLUS_CHUCK { $$ = ae_op_plus_chuck; }
422 | MINUS_CHUCK { $$ = ae_op_minus_chuck; }
423 | TIMES_CHUCK { $$ = ae_op_times_chuck; }
424 | DIVIDE_CHUCK { $$ = ae_op_divide_chuck; }
425 | SHIFT_RIGHT_CHUCK { $$ = ae_op_shift_right_chuck; }
426 | SHIFT_LEFT_CHUCK { $$ = ae_op_shift_left_chuck; }
427 | PERCENT_CHUCK { $$ = ae_op_percent_chuck; }
428 | UNCHUCK { $$ = ae_op_unchuck; }
429 | UPCHUCK { $$ = ae_op_upchuck; }
430 | S_AND_CHUCK { $$ = ae_op_s_and_chuck; }
431 | S_OR_CHUCK { $$ = ae_op_s_or_chuck; }
432 | S_XOR_CHUCK { $$ = ae_op_s_xor_chuck; }
433 ;
434
435arrow_operator
436 : ARROW_LEFT { $$ = ae_op_arrow_left; }
437 | ARROW_RIGHT { $$ = ae_op_arrow_right; }
438 ;
439
440conditional_expression
441 : logical_or_expression { $$ = $1; }
442 | logical_or_expression QUESTION expression COLON conditional_expression
443 { $$ = new_exp_from_if( $1, $3, $5, EM_lineNum ); }
444 ;
445
446logical_or_expression
447 : logical_and_expression { $$ = $1; }
448 | logical_or_expression OR logical_and_expression
449 { $$ = new_exp_from_binary( $1, ae_op_or, $3, EM_lineNum ); }
450 ;
451
452logical_and_expression
453 : inclusive_or_expression { $$ = $1; }
454 | logical_and_expression AND inclusive_or_expression
455 { $$ = new_exp_from_binary( $1, ae_op_and, $3, EM_lineNum ); }
456 ;
457
458inclusive_or_expression
459 : exclusive_or_expression { $$ = $1; }
460 | inclusive_or_expression S_OR exclusive_or_expression
461 { $$ = new_exp_from_binary( $1, ae_op_s_or, $3, EM_lineNum ); }
462 ;
463
464exclusive_or_expression
465 : and_expression { $$ = $1; }
466 | exclusive_or_expression S_XOR and_expression
467 { $$ = new_exp_from_binary( $1, ae_op_s_xor, $3, EM_lineNum ); }
468 ;
469
470and_expression
471 : equality_expression { $$ = $1; }
472 | and_expression S_AND equality_expression
473 { $$ = new_exp_from_binary( $1, ae_op_s_and, $3, EM_lineNum ); }
474 ;
475
476equality_expression
477 : relational_expression { $$ = $1; }
478 | equality_expression EQ relational_expression
479 { $$ = new_exp_from_binary( $1, ae_op_eq, $3, EM_lineNum ); }
480 | equality_expression NEQ relational_expression
481 { $$ = new_exp_from_binary( $1, ae_op_neq, $3, EM_lineNum ); }
482 ;
483
484relational_expression
485 : shift_expression { $$ = $1; }
486 | relational_expression LT shift_expression
487 { $$ = new_exp_from_binary( $1, ae_op_lt, $3, EM_lineNum ); }
488 | relational_expression GT shift_expression
489 { $$ = new_exp_from_binary( $1, ae_op_gt, $3, EM_lineNum ); }
490 | relational_expression LE shift_expression
491 { $$ = new_exp_from_binary( $1, ae_op_le, $3, EM_lineNum ); }
492 | relational_expression GE shift_expression
493 { $$ = new_exp_from_binary( $1, ae_op_ge, $3, EM_lineNum ); }
494 ;
495
496shift_expression
497 : additive_expression { $$ = $1; }
498 | shift_expression SHIFT_LEFT additive_expression
499 { $$ = new_exp_from_binary( $1, ae_op_shift_left, $3, EM_lineNum ); }
500 | shift_expression SHIFT_RIGHT additive_expression
501 { $$ = new_exp_from_binary( $1, ae_op_shift_right, $3, EM_lineNum ); }
502 ;
503
504additive_expression
505 : multiplicative_expression { $$ = $1; }
506 | additive_expression PLUS multiplicative_expression
507 { $$ = new_exp_from_binary( $1, ae_op_plus, $3, EM_lineNum ); }
508 | additive_expression MINUS multiplicative_expression
509 { $$ = new_exp_from_binary( $1, ae_op_minus, $3, EM_lineNum ); }
510 ;
511
512multiplicative_expression
513 : tilda_expression { $$ = $1; }
514 | multiplicative_expression TIMES tilda_expression
515 { $$ = new_exp_from_binary( $1, ae_op_times, $3, EM_lineNum ); }
516 | multiplicative_expression DIVIDE tilda_expression
517 { $$ = new_exp_from_binary( $1, ae_op_divide, $3, EM_lineNum ); }
518 | multiplicative_expression PERCENT tilda_expression
519 { $$ = new_exp_from_binary( $1, ae_op_percent, $3, EM_lineNum ); }
520 ;
521
522tilda_expression
523 : cast_expression { $$ = $1; }
524 | tilda_expression TILDA cast_expression
525 { $$ = new_exp_from_binary( $1, ae_op_tilda, $3, EM_lineNum ); }
526 ;
527
528cast_expression
529 : unary_expression { $$ = $1; }
530 | cast_expression DOLLAR type_decl
531 { $$ = new_exp_from_cast( $3, $1, EM_lineNum ); }
532 ;
533
534unary_expression
535 : dur_expression { $$ = $1; }
536 | PLUSPLUS unary_expression
537 { $$ = new_exp_from_unary( ae_op_plusplus, $2, EM_lineNum ); }
538 | MINUSMINUS unary_expression
539 { $$ = new_exp_from_unary( ae_op_minusminus, $2, EM_lineNum ); }
540 | unary_operator unary_expression
541 { $$ = new_exp_from_unary( $1, $2, EM_lineNum ); }
542 | TYPEOF unary_expression
543 { $$ = new_exp_from_unary( ae_op_typeof, $2, EM_lineNum ); }
544 | SIZEOF unary_expression
545 { $$ = new_exp_from_unary( ae_op_sizeof, $2, EM_lineNum ); }
546 | NEW type_decl
547 { $$ = new_exp_from_unary2( ae_op_new, $2, NULL, EM_lineNum ); }
548 | NEW type_decl array_exp
549 { $$ = new_exp_from_unary2( ae_op_new, $2, $3, EM_lineNum ); }
550// | SPORK TILDA code_segment
551// { $$ = new_exp_from_unary3( ae_op_spork, $3, EM_lineNum ); }
552 ;
553
554unary_operator
555 : PLUS { $$ = ae_op_plus; }
556 | MINUS { $$ = ae_op_minus; }
557 | TILDA { $$ = ae_op_tilda; }
558 | EXCLAMATION { $$ = ae_op_exclamation; }
559 | TIMES { $$ = ae_op_times; }
560 | SPORK TILDA { $$ = ae_op_spork; }
561 // | S_AND { $$ = ae_op_s_and; }
562 ;
563
564dur_expression
565 : postfix_expression
566 | dur_expression COLONCOLON postfix_expression
567 { $$ = new_exp_from_dur( $1, $3, EM_lineNum ); }
568 ;
569
570postfix_expression
571 : primary_expression { $$ = $1; }
572 | postfix_expression array_exp
573 { $$ = new_exp_from_array( $1, $2, EM_lineNum ); }
574 | postfix_expression LPAREN RPAREN
575 { $$ = new_exp_from_func_call( $1, NULL, EM_lineNum ); }
576 | postfix_expression LPAREN expression RPAREN
577 { $$ = new_exp_from_func_call( $1, $3, EM_lineNum ); }
578 | postfix_expression DOT ID
579 { $$ = new_exp_from_member_dot( $1, $3, EM_lineNum ); }
580 | postfix_expression PLUSPLUS
581 { $$ = new_exp_from_postfix( $1, ae_op_plusplus, EM_lineNum ); }
582 | postfix_expression MINUSMINUS
583 { $$ = new_exp_from_postfix( $1, ae_op_minusminus, EM_lineNum ); }
584 ;
585
586// 1.3.3.0: added CHAR_LIT - spencer
587primary_expression
588 : ID { $$ = new_exp_from_id( $1, EM_lineNum ); }
589 | NUM { $$ = new_exp_from_int( $1, EM_lineNum ); }
590 | FLOAT { $$ = new_exp_from_float( $1, EM_lineNum ); }
591 | STRING_LIT { $$ = new_exp_from_str( $1, EM_lineNum ); }
592 | CHAR_LIT { $$ = new_exp_from_char( $1, EM_lineNum ); }
593 | array_exp { $$ = new_exp_from_array_lit( $1, EM_lineNum ); }
594 | complex_exp { $$ = new_exp_from_complex( $1, EM_lineNum ); }
595 | polar_exp { $$ = new_exp_from_polar( $1, EM_lineNum ); }
596 | vec_exp { $$ = new_exp_from_vec( $1, EM_lineNum ); }
597 | L_HACK expression R_HACK { $$ = new_exp_from_hack( $2, EM_lineNum ); }
598 | LPAREN expression RPAREN { $$ = $2; }
599 | LPAREN RPAREN { $$ = new_exp_from_nil( EM_lineNum ); }
600 ;
core/chuck_absyn.cpp+0−972
@@ -1,972 +0,0 @@
1/*----------------------------------------------------------------------------
2 ChucK Concurrent, On-the-fly Audio Programming Language
3 Compiler and Virtual Machine
4
5 Copyright (c) 2004 Ge Wang and Perry R. Cook. All rights reserved.
6 http://chuck.stanford.edu/
7 http://chuck.cs.princeton.edu/
8
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.
13
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.
18
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-----------------------------------------------------------------------------*/
24
25//-----------------------------------------------------------------------------
26// file: chuck_absyn.cpp
27// desc: chuck abstract syntax
28//
29// author: Ge Wang (ge@ccrma.stanford.edu | gewang@cs.princeton.edu)
30// date: Autumn 2002
31//-----------------------------------------------------------------------------
32#include <stdlib.h>
33#include <stdio.h>
34#include "chuck_absyn.h"
35#include "chuck_utils.h"
36
37
38a_Program new_program( a_Section section, int pos )
39{
40 a_Program a = (a_Program)checked_malloc( sizeof( struct a_Program_ ) );
41 a->section = section;
42 a->linepos = pos;
43
44 return a;
45}
46
47a_Program prepend_program( a_Section section, a_Program program, int pos )
48{
49 a_Program a = new_program( section, pos );
50 a->next = program;
51 a->linepos = pos;
52
53 return a;
54}
55
56a_Section new_section_stmt( a_Stmt_List list, int pos )
57{
58 a_Section a = (a_Section)checked_malloc( sizeof( struct a_Section_ ) );
59 a->s_type = ae_section_stmt;
60 a->stmt_list = list;
61 a->linepos = pos;
62
63 return a;
64}
65
66a_Section new_section_func_def( a_Func_Def func_def, int pos )
67{
68 a_Section a = (a_Section)checked_malloc( sizeof( struct a_Section_) );
69 a->s_type = ae_section_func;
70 a->func_def = func_def;
71 a->linepos = pos;
72
73 return a;
74}
75
76a_Section new_section_class_def( a_Class_Def class_def, int pos )
77{
78 a_Section a = (a_Section)checked_malloc( sizeof( struct a_Section_) );
79 a->s_type = ae_section_class;
80 a->class_def = class_def;
81 a->linepos = pos;
82
83 return a;
84}
85
86a_Stmt_List new_stmt_list( a_Stmt stmt, int pos )
87{
88 a_Stmt_List a = (a_Stmt_List)checked_malloc( sizeof( struct a_Stmt_List_ ) );
89 a->stmt = stmt;
90 a->next = NULL;
91 a->linepos = pos;
92
93 return a;
94}
95
96a_Stmt_List prepend_stmt_list( a_Stmt stmt, a_Stmt_List stmt_list, int pos )
97{
98 a_Stmt_List a = new_stmt_list( stmt, pos );
99 a->next = stmt_list;
100 a->linepos = pos;
101
102 return a;
103}
104
105a_Stmt new_stmt_from_expression( a_Exp exp, int pos )
106{
107 a_Stmt a = (a_Stmt)checked_malloc( sizeof( struct a_Stmt_ ) );
108 a->s_type = ae_stmt_exp;
109 a->stmt_exp = exp;
110 a->linepos = pos;
111
112 return a;
113}
114
115a_Stmt new_stmt_from_code( a_Stmt_List stmt_list, int pos )
116{
117 a_Stmt a = (a_Stmt)checked_malloc( sizeof( struct a_Stmt_ ) );
118 a->s_type = ae_stmt_code;
119 a->stmt_code.stmt_list = stmt_list;
120 a->linepos = pos;
121 a->stmt_code.linepos = pos;
122 a->stmt_code.self = a;
123
124 return a;
125}
126
127a_Stmt new_stmt_from_if( a_Exp cond, a_Stmt if_body, a_Stmt else_body, int pos )
128{
129 a_Stmt a = (a_Stmt)checked_malloc( sizeof( struct a_Stmt_ ) );
130 a->s_type = ae_stmt_if;
131 a->stmt_if.cond = cond;
132 a->stmt_if.if_body = if_body;
133 a->stmt_if.else_body = else_body;
134 a->linepos = pos;
135 a->stmt_if.linepos = pos;
136 a->stmt_if.self = a;
137
138 return a;
139}
140
141a_Stmt new_stmt_from_while( a_Exp cond, a_Stmt body, int pos )
142{
143 a_Stmt a = (a_Stmt)checked_malloc( sizeof( struct a_Stmt_ ) );
144 a->s_type = ae_stmt_while;
145 a->stmt_while.is_do = 0;
146 a->stmt_while.cond = cond;
147 a->stmt_while.body = body;
148 a->linepos = pos;
149 a->stmt_while.linepos = pos;
150 a->stmt_while.self = a;
151
152 return a;
153}
154
155a_Stmt new_stmt_from_do_while( a_Exp cond, a_Stmt body, int pos )
156{
157 a_Stmt a = (a_Stmt)checked_malloc( sizeof( struct a_Stmt_ ) );
158 a->s_type = ae_stmt_while;
159 a->stmt_while.is_do = 1;
160 a->stmt_while.cond = cond;
161 a->stmt_while.body = body;
162 a->linepos = pos;
163 a->stmt_while.linepos = pos;
164 a->stmt_while.self = a;
165
166 return a;
167}
168
169a_Stmt new_stmt_from_until( a_Exp cond, a_Stmt body, int pos )
170{
171 a_Stmt a = (a_Stmt)checked_malloc( sizeof( struct a_Stmt_ ) );
172 a->s_type = ae_stmt_until;
173 a->stmt_until.is_do = 0;
174 a->stmt_until.cond = cond;
175 a->stmt_until.body = body;
176 a->linepos = pos;
177 a->stmt_until.linepos = pos;
178 a->stmt_until.self = a;
179
180 return a;
181}
182
183a_Stmt new_stmt_from_do_until( a_Exp cond, a_Stmt body, int pos )
184{
185 a_Stmt a = (a_Stmt)checked_malloc( sizeof( struct a_Stmt_ ) );
186 a->s_type = ae_stmt_until;
187 a->stmt_until.is_do = 1;
188 a->stmt_until.cond = cond;
189 a->stmt_until.body = body;
190 a->linepos = pos;
191 a->stmt_until.linepos = pos;
192 a->stmt_until.self = a;
193
194 return a;
195}
196
197a_Stmt new_stmt_from_for( a_Stmt c1, a_Stmt c2, a_Exp c3, a_Stmt body, int pos )
198{
199 a_Stmt a = (a_Stmt)checked_malloc( sizeof( struct a_Stmt_ ) );
200 a->s_type = ae_stmt_for;
201 a->stmt_for.c1 = c1;
202 a->stmt_for.c2 = c2;
203 a->stmt_for.c3 = c3;
204 a->stmt_for.body = body;
205 a->linepos = pos;
206 a->stmt_for.linepos = pos;
207 a->stmt_for.self = a;
208
209 return a;
210}
211
212a_Stmt new_stmt_from_loop( a_Exp cond, a_Stmt body, int pos )
213{
214 a_Stmt a = (a_Stmt)checked_malloc( sizeof( struct a_Stmt_ ) );
215 a->s_type = ae_stmt_loop;
216 a->stmt_loop.cond = cond;
217 a->stmt_loop.body = body;
218 a->linepos = pos;
219 a->stmt_loop.linepos = pos;
220 a->stmt_loop.self = a;
221
222 return a;
223}
224
225a_Stmt new_stmt_from_switch( a_Exp val, int pos )
226{
227 a_Stmt a = (a_Stmt)checked_malloc( sizeof( struct a_Stmt_ ) );
228 a->s_type = ae_stmt_switch;
229 a->stmt_switch.val = val;
230 a->linepos = pos;
231 a->stmt_switch.linepos = pos;
232 a->stmt_switch.self = a;
233
234 return a;
235}
236
237a_Stmt new_stmt_from_break( int pos )
238{
239 a_Stmt a = (a_Stmt)checked_malloc( sizeof( struct a_Stmt_ ) );
240 a->s_type = ae_stmt_break;
241 a->linepos = pos;
242 a->stmt_break.linepos = pos;
243 a->stmt_break.self = a;
244
245 return a;
246}
247
248a_Stmt new_stmt_from_continue( int pos )
249{
250 a_Stmt a = (a_Stmt)checked_malloc( sizeof( struct a_Stmt_ ) );
251 a->s_type = ae_stmt_continue;
252 a->linepos = pos;
253 a->stmt_continue.linepos = pos;
254 a->stmt_continue.self = a;
255
256 return a;
257}
258
259a_Stmt new_stmt_from_return( a_Exp exp, int pos )
260{
261 a_Stmt a = (a_Stmt)checked_malloc( sizeof( struct a_Stmt_ ) );
262 a->s_type = ae_stmt_return;
263 a->stmt_return.val = exp;
264 a->linepos = pos;
265 a->stmt_return.linepos = pos;
266 a->stmt_return.self = a;
267
268 return a;
269}
270
271a_Stmt new_stmt_from_label( c_str xid, int pos )
272{
273 a_Stmt a = (a_Stmt)checked_malloc( sizeof( struct a_Stmt_ ) );
274 a->s_type = ae_stmt_gotolabel;
275 a->stmt_gotolabel.name = insert_symbol( xid );
276 a->linepos = pos;
277 a->stmt_gotolabel.linepos = pos;
278 a->stmt_gotolabel.self = a;
279
280 return a;
281}
282
283a_Stmt new_stmt_from_case( a_Exp exp, int pos )
284{
285 a_Stmt a = (a_Stmt)checked_malloc( sizeof( struct a_Stmt_ ) );
286 a->s_type = ae_stmt_case;
287 a->stmt_case.exp = exp;
288 a->linepos = pos;
289 a->stmt_case.linepos = pos;
290 a->stmt_case.self = a;
291
292 return a;
293}
294
295a_Exp prepend_expression( a_Exp exp, a_Exp list, int pos )
296{
297 exp->next = list;
298 return exp;
299}
300
301a_Exp new_exp_from_binary( a_Exp lhs, ae_Operator oper, a_Exp rhs, int pos )
302{
303 a_Exp a = (a_Exp)checked_malloc( sizeof( struct a_Exp_ ) );
304 a->s_type = ae_exp_binary;
305 a->s_meta = ae_meta_value;
306 a->binary.lhs = lhs;
307 a->binary.op = oper;
308 a->binary.rhs = rhs;
309 a->linepos = pos;
310 a->binary.linepos = pos;
311 a->binary.self = a;
312
313 return a;
314}
315
316a_Exp new_exp_from_unary( ae_Operator oper, a_Exp exp, int pos )
317{
318 a_Exp a = (a_Exp)checked_malloc( sizeof( struct a_Exp_ ) );
319 a->s_type = ae_exp_unary;
320 a->s_meta = exp->s_meta;
321 a->unary.op = oper;
322 a->unary.exp = exp;
323 a->linepos = pos;
324 a->unary.linepos = pos;
325 a->unary.self = a;
326
327 return a;
328}
329
330a_Exp new_exp_from_unary2( ae_Operator oper, a_Type_Decl type,
331 a_Array_Sub array, int pos )
332{
333 a_Exp a = (a_Exp)checked_malloc( sizeof( struct a_Exp_ ) );
334 a->s_type = ae_exp_unary;
335 a->s_meta = ae_meta_value;
336 a->unary.op = oper;
337 a->unary.type = type;
338 a->unary.array = array;
339 a->linepos = pos;
340 a->unary.linepos = pos;
341 a->unary.self = a;
342
343 return a;
344}
345
346a_Exp new_exp_from_unary3( ae_Operator oper, a_Stmt code, int pos )
347{
348 a_Exp a = (a_Exp)checked_malloc( sizeof( struct a_Exp_ ) );
349 a->s_type = ae_exp_unary;
350 a->s_meta = ae_meta_value;
351 a->unary.op = oper;
352 a->unary.code = code;
353 a->linepos = pos;
354 a->unary.linepos = pos;
355 a->unary.self = a;
356
357 return a;
358}
359
360a_Exp new_exp_from_cast( a_Type_Decl type, a_Exp exp, int pos )
361{
362 a_Exp a = (a_Exp)checked_malloc( sizeof( struct a_Exp_ ) );
363 a->s_type = ae_exp_cast;
364 a->s_meta = ae_meta_value;
365 a->cast.type = type;
366 a->cast.exp = exp;
367 a->linepos = pos;
368 a->cast.linepos = pos;
369 a->cast.self = a;
370
371 return a;
372}
373
374a_Exp new_exp_from_array( a_Exp base, a_Array_Sub indices, int pos )
375{
376 a_Exp a = (a_Exp)checked_malloc( sizeof( struct a_Exp_ ) );
377 a->s_type = ae_exp_array;
378 a->s_meta = ae_meta_var;
379 a->array.base = base;
380 a->array.indices = indices;
381 a->linepos = pos;
382 a->array.linepos = pos;
383 a->array.self = a;
384
385 return a;
386}
387
388a_Exp new_exp_from_func_call( a_Exp base, a_Exp args, int pos )
389{
390 a_Exp a = (a_Exp)checked_malloc( sizeof( struct a_Exp_ ) );
391 a->s_type = ae_exp_func_call;
392 a->s_meta = ae_meta_value;
393 a->func_call.func = base;
394 a->func_call.args = args;
395 a->linepos = pos;
396 a->func_call.linepos = pos;
397 a->func_call.self = a;
398
399 return a;
400}
401
402a_Exp new_exp_from_member_dot( a_Exp base, c_str xid, int pos )
403{
404 a_Exp a = (a_Exp)checked_malloc( sizeof( struct a_Exp_ ) );
405 a->s_type = ae_exp_dot_member;
406 a->s_meta = ae_meta_var;
407 a->dot_member.base = base;
408 a->dot_member.xid = insert_symbol( xid );
409 a->linepos = pos;
410 a->dot_member.linepos = pos;
411 a->dot_member.self = a;
412
413 return a;
414}
415
416a_Exp new_exp_from_postfix( a_Exp base, ae_Operator op, int pos )
417{
418 a_Exp a = (a_Exp)checked_malloc( sizeof( struct a_Exp_ ) );
419 a->s_type = ae_exp_postfix;
420 a->s_meta = ae_meta_var;
421 a->postfix.exp = base;
422 a->postfix.op = op;
423 a->linepos = pos;
424 a->postfix.linepos = pos;
425 a->postfix.self = a;
426
427 return a;
428}
429
430a_Exp new_exp_from_dur( a_Exp base, a_Exp unit, int pos )
431{
432 a_Exp a = (a_Exp)checked_malloc( sizeof( struct a_Exp_ ) );
433 a->s_type = ae_exp_dur;
434 a->s_meta = ae_meta_value;
435 a->dur.base = base;
436 a->dur.unit = unit;
437 a->linepos = pos;
438 a->dur.linepos = pos;
439 a->dur.self = a;
440
441 return a;
442}
443
444a_Exp new_exp_from_id( c_str xid, int pos )
445{
446 a_Exp a = (a_Exp)checked_malloc( sizeof( struct a_Exp_ ) );
447 a->s_type = ae_exp_primary;
448 a->s_meta = ae_meta_var;
449 a->primary.s_type = ae_primary_var;
450 a->primary.var = insert_symbol( xid );
451 a->linepos = pos;
452 a->primary.linepos = pos;
453 a->primary.self = a;
454
455 return a;
456}
457
458a_Exp new_exp_from_int( long num, int pos )
459{
460 a_Exp a = (a_Exp)checked_malloc( sizeof( struct a_Exp_ ) );
461 a->s_type = ae_exp_primary;
462 a->s_meta = ae_meta_value;
463 a->primary.s_type = ae_primary_num;
464 a->primary.num = num;
465 a->linepos = pos;
466 a->primary.linepos = pos;
467 a->primary.self = a;
468
469 return a;
470}
471
472a_Exp new_exp_from_float( double num, int pos )
473{
474 a_Exp a = (a_Exp)checked_malloc( sizeof( struct a_Exp_ ) );
475 a->s_type = ae_exp_primary;
476 a->s_meta = ae_meta_value;
477 a->primary.s_type = ae_primary_float;
478 a->primary.fnum = num;
479 a->linepos = pos;
480 a->primary.linepos = pos;
481 a->primary.self = a;
482
483 return a;
484}
485
486a_Exp new_exp_from_str( c_str str, int pos )
487{
488 a_Exp a = (a_Exp)checked_malloc( sizeof( struct a_Exp_ ) );
489 a->s_type = ae_exp_primary;
490 a->s_meta = ae_meta_value;
491 a->primary.s_type = ae_primary_str;
492 a->primary.str = str;
493 a->linepos = pos;
494 a->primary.linepos = pos;
495 a->primary.self = a;
496
497 return a;
498}
499
500a_Exp new_exp_from_char( c_str chr, int pos )
501{
502 a_Exp a = (a_Exp)checked_malloc( sizeof( struct a_Exp_ ) );
503 a->s_type = ae_exp_primary;
504 a->s_meta = ae_meta_value;
505 a->primary.s_type = ae_primary_char;
506 a->primary.chr = chr;
507 a->linepos = pos;
508 a->primary.linepos = pos;
509 a->primary.self = a;
510
511 return a;
512}
513
514a_Exp new_exp_from_array_lit( a_Array_Sub exp_list, int pos )
515{
516 a_Exp a = (a_Exp)checked_malloc( sizeof( struct a_Exp_ ) );
517 a->s_type = ae_exp_primary;
518 a->s_meta = ae_meta_value;
519 a->primary.s_type = ae_primary_array;
520 a->primary.array = exp_list;
521 a->linepos = pos;
522 a->primary.linepos = pos;
523 a->primary.self = a;
524
525 return a;
526}
527
528a_Exp new_exp_from_if( a_Exp cond, a_Exp if_exp, a_Exp else_exp, int pos )
529{
530 a_Exp a = (a_Exp)checked_malloc( sizeof( struct a_Exp_ ) );
531 a->s_type = ae_exp_if;
532 a->s_meta = ( ( if_exp->s_meta == ae_meta_var &&
533 else_exp->s_meta == ae_meta_var ) ? ae_meta_var : ae_meta_value );
534 a->exp_if.cond = cond;
535 a->exp_if.if_exp = if_exp;
536 a->exp_if.else_exp = else_exp;
537 a->linepos = pos;
538 a->exp_if.linepos = pos;
539 a->exp_if.self = a;
540
541 return a;
542}
543
544a_Exp new_exp_decl_external( a_Type_Decl type, a_Var_Decl_List var_decl_list, int is_static, int pos )
545{
546 a_Exp a = new_exp_decl( type, var_decl_list, is_static, pos );
547 a->decl.is_external = 1;
548
549 return a;
550}
551
552a_Exp new_exp_decl( a_Type_Decl type, a_Var_Decl_List var_decl_list, int is_static, int pos )
553{
554 a_Exp a = (a_Exp)checked_malloc( sizeof( struct a_Exp_ ) );
555 a->s_type = ae_exp_decl;
556 a->s_meta = ae_meta_var;
557 a->decl.type = type;
558 a->decl.var_decl_list = var_decl_list;
559 a->linepos = pos;
560 a->decl.is_static = is_static;
561 a->decl.linepos = pos;
562 a->decl.self = a;
563
564 return a;
565}
566
567a_Exp new_exp_from_hack( a_Exp exp, int pos )
568{
569 a_Exp a = (a_Exp)checked_malloc( sizeof( struct a_Exp_ ) );
570 a->s_type = ae_exp_primary;
571 a->s_meta = ae_meta_value;
572 a->primary.s_type = ae_primary_hack;
573 a->primary.exp = exp;
574 a->primary.linepos = pos;
575 a->linepos = pos;
576 a->primary.self = a;
577
578 return a;
579}
580
581a_Exp new_exp_from_complex( a_Complex exp, int pos )
582{
583 a_Exp a = (a_Exp)checked_malloc( sizeof( struct a_Exp_ ) );
584 a->s_type = ae_exp_primary;
585 a->s_meta = ae_meta_value;
586 a->primary.s_type = ae_primary_complex;
587 a->primary.complex = exp;
588 a->primary.linepos = pos;
589 a->linepos = pos;
590 a->primary.complex->self = a;
591 a->primary.self = a;
592
593 return a;
594}
595
596a_Exp new_exp_from_polar( a_Polar exp, int pos )
597{
598 a_Exp a = (a_Exp)checked_malloc( sizeof( struct a_Exp_ ) );
599 a->s_type = ae_exp_primary;
600 a->s_meta = ae_meta_value;
601 a->primary.s_type = ae_primary_polar;
602 a->primary.polar = exp;
603 a->primary.linepos = pos;
604 a->linepos = pos;
605 a->primary.polar->self = a;
606 a->primary.self = a;
607
608 return a;
609}
610
611a_Exp new_exp_from_vec( a_Vec exp, int pos ) // ge: added 1.3.5.3
612{
613 a_Exp a = (a_Exp)checked_malloc( sizeof( struct a_Exp_ ) );
614 a->s_type = ae_exp_primary;
615 a->s_meta = ae_meta_value;
616 a->primary.s_type = ae_primary_vec;
617 a->primary.vec = exp;
618 a->primary.linepos = pos;
619 a->linepos = pos;
620 a->primary.vec->self = a;
621 a->primary.self = a;
622
623 return a;
624}
625
626a_Exp new_exp_from_nil( int pos )
627{
628 a_Exp a = (a_Exp)checked_malloc( sizeof( struct a_Exp_ ) );
629 a->s_type = ae_exp_primary;
630 a->s_meta = ae_meta_value;
631 a->primary.s_type = ae_primary_nil;
632 a->primary.linepos = pos;
633 a->linepos = pos;
634 a->primary.self = a;
635
636 return a;
637}
638
639a_Var_Decl new_var_decl( c_constr xid, a_Array_Sub array, int pos )
640{
641 a_Var_Decl a = (a_Var_Decl)checked_malloc( sizeof( struct a_Var_Decl_ ) );
642 a->xid = insert_symbol(xid);
643 a->array = array;
644 a->linepos = pos;
645
646 return a;
647}
648
649a_Var_Decl_List new_var_decl_list( a_Var_Decl var_decl, int pos )
650{
651 a_Var_Decl_List a = (a_Var_Decl_List)checked_malloc(
652 sizeof( struct a_Var_Decl_List_ ) );
653 a->var_decl = var_decl;
654 a->linepos = pos;
655
656 return a;
657}
658
659a_Var_Decl_List prepend_var_decl_list( a_Var_Decl var_decl, a_Var_Decl_List list, int pos )
660{
661 a_Var_Decl_List a = new_var_decl_list( var_decl, pos );
662 a->next = list;
663
664 return a;
665}
666
667a_Type_Decl new_type_decl( a_Id_List type, int ref, int pos )
668{
669 a_Type_Decl a = (a_Type_Decl)checked_malloc(
670 sizeof( struct a_Type_Decl_ ) );
671 a->xid = type;
672 a->ref = ref;
673 a->linepos = pos;
674
675 return a;
676}
677
678a_Type_Decl add_type_decl_array( a_Type_Decl a, a_Array_Sub array, int pos )
679{
680 assert( a->array == NULL );
681 a->array = array;
682
683 return a;
684}
685
686a_Arg_List new_arg_list( a_Type_Decl type_decl, a_Var_Decl var_decl, int pos )
687{
688 a_Arg_List a = (a_Arg_List)checked_malloc(
689 sizeof( struct a_Arg_List_ ) );
690 a->type_decl = type_decl;
691 a->var_decl = var_decl;
692 a->next = NULL;
693 a->linepos = pos;
694
695 return a;
696}
697
698a_Arg_List prepend_arg_list( a_Type_Decl type_decl, a_Var_Decl var_decl,
699 a_Arg_List arg_list, int pos )
700{
701 a_Arg_List a = new_arg_list( type_decl, var_decl, pos );
702 a->next = arg_list;
703 a->linepos = pos;
704
705 return a;
706}
707
708a_Func_Def new_func_def( ae_Keyword func_decl, ae_Keyword static_decl,
709 a_Type_Decl type_decl, c_str name,
710 a_Arg_List arg_list, a_Stmt code, int pos )
711{
712 a_Func_Def a = (a_Func_Def)checked_malloc(
713 sizeof( struct a_Func_Def_ ) );
714 a->func_decl = func_decl;
715 a->static_decl = static_decl;
716 a->type_decl = type_decl;
717 a->name = insert_symbol( name );
718 a->arg_list = arg_list;
719 a->s_type = ae_func_user;
720 a->code = code;
721 a->linepos = pos;
722
723 return a;
724}
725
726a_Class_Def new_class_def( ae_Keyword class_decl, a_Id_List name,
727 a_Class_Ext ext, a_Class_Body body, int pos )
728{
729 a_Class_Def a = (a_Class_Def)checked_malloc( sizeof( struct a_Class_Def_ ) );
730 a->decl = class_decl;
731 a->name = name;
732 a->ext = ext;
733 a->body = body;
734 a->linepos = pos;
735
736 return a;
737}
738
739a_Class_Def new_iface_def( ae_Keyword class_decl, a_Id_List name,
740 a_Class_Ext ext, a_Class_Body body, int pos )
741{
742 a_Class_Def a = new_class_def( class_decl, name, ext, body, pos );
743 a->iface = 1;
744
745 return a;
746}
747
748a_Class_Body new_class_body( a_Section section, int pos )
749{
750 a_Class_Body a = (a_Class_Body)checked_malloc( sizeof( struct a_Class_Body_ ) );
751 a->section = section;
752 a->linepos = pos;
753
754 return a;
755}
756
757a_Class_Body prepend_class_body( a_Section section, a_Class_Body body, int pos )
758{
759 a_Class_Body a = new_class_body( section, pos );
760 a->next = body;
761 a->linepos = pos;
762
763 return a;
764}
765
766a_Class_Ext new_class_ext( a_Id_List extend_id, a_Id_List impl_list, int pos )
767{
768 a_Class_Ext a = (a_Class_Ext)checked_malloc( sizeof( struct a_Class_Ext_ ) );
769 a->extend_id = extend_id;
770 a->impl_list = impl_list;
771 a->linepos = pos;
772
773 return a;
774}
775
776a_Id_List new_id_list( c_constr xid, int pos )
777{
778 a_Id_List a = (a_Id_List)checked_malloc( sizeof( struct a_Id_List_ ) );
779 a->xid = insert_symbol( xid );
780 a->next = NULL;
781 a->linepos = pos;
782
783 return a;
784}
785
786a_Id_List prepend_id_list( c_constr xid, a_Id_List list, int pos )
787{
788 a_Id_List a = new_id_list( xid, pos );
789 a->next = list;
790 a->linepos = pos;
791
792 return a;
793}
794
795void clean_exp( a_Exp exp )
796{
797 if( !exp ) return;
798 clean_exp( exp->next );
799 free( exp );
800}
801
802a_Array_Sub new_array_sub( a_Exp exp, int pos )
803{
804 a_Array_Sub a = (a_Array_Sub)checked_malloc( sizeof( struct a_Array_Sub_ ) );
805 a->exp_list = exp;
806 a->depth = 1;
807 a->linepos = pos;
808
809 // make sure no multi
810 /* if( exp && exp->next )
811 {
812 // primary exp?
813 if( is_primary )
814 {
815 a->exp_list = NULL;
816 a->exp_multi = exp;
817 }
818 else
819 {
820 a->err_num = 1; // multi
821 a->err_pos = exp->linepos; // set error for type-checker
822 goto error;
823 }
824 } */
825
826 return a;
827
828/* error:
829 clean_exp( exp );
830 a->exp_list = NULL;
831 return a; */
832}
833
834a_Array_Sub prepend_array_sub( a_Array_Sub a, a_Exp exp, int pos )
835{
836 // if already error
837 if( a->err_num ) goto error;
838
839 // make sure no multi
840 if( exp && exp->next )
841 {
842 a->err_num = 1; // multi
843 a->err_pos = exp->linepos; // set error for type-checker
844 goto error;
845 }
846
847 // empty or not
848 if( (exp && !a->exp_list) || (!exp && a->exp_list) )
849 {
850 a->err_num = 2; // partial
851 a->err_pos = pos; // set error for type-checker
852 goto error;
853 }
854
855 // prepend
856 if( exp )
857 {
858 exp->next = a->exp_list;
859 a->exp_list = exp;
860 }
861
862 // count
863 a->depth++;
864 return a;
865
866error:
867 clean_exp( exp );
868 return a;
869}
870
871a_Complex new_complex( a_Exp re, int pos )
872{
873 a_Complex a = (a_Complex)checked_malloc( sizeof( struct a_Complex_ ) );
874 a->re = re;
875 if( re ) a->im = re->next;
876 a->linepos = pos;
877
878 return a;
879}
880
881a_Polar new_polar( a_Exp mod, int pos )
882{
883 a_Polar a = (a_Polar)checked_malloc( sizeof( struct a_Polar_ ) );
884 a->mod = mod;
885 if( mod ) a->phase = mod->next;
886 a->linepos = pos;
887
888 return a;
889}
890
891a_Vec new_vec( a_Exp e, int pos ) // ge: added 1.3.5.3
892{
893 a_Vec a = (a_Vec)checked_malloc( sizeof( struct a_Vec_ ) );
894 a->args = e;
895 while( e ) // count number of dims
896 {
897 a->numdims++;
898 e = e->next;
899 }
900 a->linepos = pos;
901
902 return a;
903}
904
905void delete_id_list( a_Id_List x )
906{
907 if( !x ) return;
908
909 a_Id_List curr = x, next = x->next, temp;
910
911 while( curr )
912 {
913 temp = curr;
914 curr = next;
915 next = temp->next;
916 free( temp );
917 }
918}
919
920
921static const char * op_str[] = {
922 "+",
923 "-",
924 "*",
925 "/",
926 "==",
927 "!=",
928 "<",
929 "<=",
930 ">",
931 ">=",
932 "&&",
933 "||",
934 "|",
935 "&",
936 "<<",
937 ">>",
938 "%",
939 "^",
940 "=>",
941 "+=>",
942 "-=>",
943 "*=>",
944 "/=>",
945 "&=>",
946 "|=>",
947 "^=>",
948 ">>=>",
949 "<<=>",
950 "%=>",
951 "->",
952 "++",
953 "--",
954 "~",
955 "!",
956 "@=>",
957 "=<",
958 "spork ~",
959 "typeof",
960 "sizeof",
961 "new"
962};
963
964
965const char * op2str( ae_Operator op )
966{
967 t_CKINT index = (t_CKINT)op;
968 if( index < 0 || index >= (t_CKINT)(sizeof(op_str)/sizeof(char *)) )
969 return "[non-existent operator]";
970
971 return op_str[index];
972}
core/chuck_absyn.h+0−406
@@ -1,406 +0,0 @@
1/*----------------------------------------------------------------------------
2 ChucK Concurrent, On-the-fly Audio Programming Language
3 Compiler and Virtual Machine
4
5 Copyright (c) 2004 Ge Wang and Perry R. Cook. All rights reserved.
6 http://chuck.stanford.edu/
7 http://chuck.cs.princeton.edu/
8
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.
13
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.
18
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-----------------------------------------------------------------------------*/
24
25//-----------------------------------------------------------------------------
26// file: chuck_absyn.h
27// desc: chuck abstract syntax
28//
29// author: Ge Wang (ge@ccrma.stanford.edu | gewang@cs.princeton.edu)
30// date: Autumn 2002
31//-----------------------------------------------------------------------------
32#ifndef __CHUCK_ABSYN_H__
33#define __CHUCK_ABSYN_H__
34
35#include "chuck_symbol.h"
36
37#if defined(_cplusplus) || defined(__cplusplus)
38extern "C" {
39#endif
40
41// pos
42typedef int a_Pos;
43
44// enum oper
45typedef enum {
46 ae_op_plus, ae_op_minus, ae_op_times, ae_op_divide,
47 ae_op_eq, ae_op_neq, ae_op_lt, ae_op_le, ae_op_gt,
48 ae_op_ge, ae_op_and, ae_op_or, ae_op_s_or, ae_op_s_and,
49 ae_op_shift_left, ae_op_shift_right, ae_op_percent,
50 ae_op_s_xor, ae_op_chuck, ae_op_plus_chuck, ae_op_minus_chuck,
51 ae_op_times_chuck, ae_op_divide_chuck, ae_op_s_and_chuck,
52 ae_op_s_or_chuck, ae_op_s_xor_chuck, ae_op_shift_right_chuck,
53 ae_op_shift_left_chuck, ae_op_percent_chuck, ae_op_s_chuck,
54 ae_op_plusplus, ae_op_minusminus, ae_op_tilda, ae_op_exclamation,
55 ae_op_at_chuck, ae_op_unchuck, ae_op_upchuck, ae_op_spork,
56 ae_op_typeof, ae_op_sizeof, ae_op_new, ae_op_arrow_left, ae_op_arrow_right
57} ae_Operator;
58
59const char * op2str( ae_Operator op );
60
61// enum key words
62typedef enum {
63 ae_key_this, ae_key_me, ae_key_func, ae_key_public, ae_key_protected,
64 ae_key_private, ae_key_static, ae_key_instance, ae_key_abstract
65} ae_Keyword;
66
67
68
69
70//-----------------------------------------------------------------------------
71// pointer types
72//-----------------------------------------------------------------------------
73typedef struct a_Program_ * a_Program;
74typedef struct a_Section_ * a_Section;
75typedef struct a_Stmt_List_ * a_Stmt_List;
76typedef struct a_Class_Def_ * a_Class_Def;
77typedef struct a_Func_Def_ * a_Func_Def;
78typedef struct a_Code_Segment_ * a_Code_Segment;
79typedef struct a_Stmt_ * a_Stmt;
80typedef struct a_Exp_ * a_Exp;
81typedef struct a_Exp_Chuck_ * a_Exp_Chuck;
82typedef struct a_Exp_Binary_ * a_Exp_Binary;
83typedef struct a_Exp_Cast_ * a_Exp_Cast;
84typedef struct a_Exp_Unary_ * a_Exp_Unary;
85typedef struct a_Exp_Postfix_ * a_Exp_Postfix;
86typedef struct a_Exp_Primary_ * a_Exp_Primary;
87typedef struct a_Exp_Dur_ * a_Exp_Dur;
88typedef struct a_Exp_Array_ * a_Exp_Array;
89typedef struct a_Exp_Func_Call_ * a_Exp_Func_Call;
90typedef struct a_Exp_Dot_Member_ * a_Exp_Dot_Member;
91typedef struct a_Exp_If_ * a_Exp_If;
92typedef struct a_Exp_Decl_ * a_Exp_Decl;
93typedef struct a_Exp_Hack_ * a_Exp_Hack;
94typedef struct a_Stmt_Code_ * a_Stmt_Code;
95typedef struct a_Stmt_If_ * a_Stmt_If;
96typedef struct a_Stmt_While_ * a_Stmt_While;
97typedef struct a_Stmt_Until_ * a_Stmt_Until;
98typedef struct a_Stmt_For_ * a_Stmt_For;
99typedef struct a_Stmt_Loop_ * a_Stmt_Loop;
100typedef struct a_Stmt_Switch_ * a_Stmt_Switch;
101typedef struct a_Stmt_Break_ * a_Stmt_Break;
102typedef struct a_Stmt_Continue_ * a_Stmt_Continue;
103typedef struct a_Stmt_Return_ * a_Stmt_Return;
104typedef struct a_Stmt_Case_ * a_Stmt_Case;
105typedef struct a_Stmt_GotoLabel_ * a_Stmt_GotoLabel;
106typedef struct a_Decl_ * a_Decl;
107typedef struct a_Var_Decl_ * a_Var_Decl;
108typedef struct a_Var_Decl_List_ * a_Var_Decl_List;
109typedef struct a_Type_Decl_ * a_Type_Decl;
110typedef struct a_Arg_List_ * a_Arg_List;
111typedef struct a_Id_List_ * a_Id_List;
112typedef struct a_Class_Ext_ * a_Class_Ext;
113typedef struct a_Class_Body_ * a_Class_Body;
114typedef struct a_Array_Sub_ * a_Array_Sub;
115typedef struct a_Complex_ * a_Complex;
116typedef struct a_Polar_ * a_Polar;
117typedef struct a_Vec_ * a_Vec; // ge: added 1.3.5.3
118
119// forward reference for type
120typedef struct Chuck_Type * t_CKTYPE;
121typedef struct Chuck_Value * t_CKVALUE;
122typedef struct Chuck_Func * t_CKFUNC;
123typedef struct Chuck_Namespace * t_CKNSPC;
124typedef struct Chuck_VM_Code * t_CKVMCODE;
125
126
127
128
129//------------------------------------------------------------------------------
130// functions
131//------------------------------------------------------------------------------
132a_Program new_program( a_Section section, int pos );
133a_Program prepend_program( a_Section section, a_Program program, int pos );
134a_Section new_section_stmt( a_Stmt_List stmt_list, int pos );
135a_Section new_section_func_def( a_Func_Def func_def, int pos );
136a_Section new_section_class_def( a_Class_Def class_def, int pos );
137a_Stmt_List new_stmt_list( a_Stmt stmt, int pos );
138a_Stmt_List prepend_stmt_list( a_Stmt stmt, a_Stmt_List stmt_list, int pos );
139a_Stmt new_stmt_from_expression( a_Exp exp, int pos );
140a_Stmt new_stmt_from_code( a_Stmt_List code, int pos );
141a_Stmt new_stmt_from_while( a_Exp cond, a_Stmt body, int pos );
142a_Stmt new_stmt_from_do_while( a_Exp cond, a_Stmt body, int pos );
143a_Stmt new_stmt_from_until( a_Exp cond, a_Stmt body, int pos );
144a_Stmt new_stmt_from_do_until( a_Exp cond, a_Stmt body, int pos );
145a_Stmt new_stmt_from_for( a_Stmt c1, a_Stmt c2, a_Exp c3, a_Stmt body, int pos );
146a_Stmt new_stmt_from_loop( a_Exp cond, a_Stmt body, int pos );
147a_Stmt new_stmt_from_if( a_Exp cond, a_Stmt if_body, a_Stmt else_body, int pos );
148a_Stmt new_stmt_from_switch( a_Exp exp, int pos );
149a_Stmt new_stmt_from_break( int pos );
150a_Stmt new_stmt_from_continue( int pos );
151a_Stmt new_stmt_from_return( a_Exp exp, int pos );
152a_Stmt new_stmt_from_label( c_str xid, int pos );
153a_Stmt new_stmt_from_case( a_Exp exp, int pos );
154a_Exp prepend_expression( a_Exp exp, a_Exp list, int pos );
155a_Exp new_exp_from_binary( a_Exp lhs, ae_Operator oper, a_Exp rhs, int pos );
156a_Exp new_exp_from_unary( ae_Operator oper, a_Exp exp, int pos );
157a_Exp new_exp_from_unary2( ae_Operator oper, a_Type_Decl type, a_Array_Sub array, int pos );
158a_Exp new_exp_from_unary3( ae_Operator oper, a_Stmt code, int pos );
159a_Exp new_exp_from_cast( a_Type_Decl type, a_Exp exp, int pos );
160a_Exp new_exp_from_array( a_Exp base, a_Array_Sub indices, int pos );
161a_Exp new_exp_from_array_lit( a_Array_Sub exp_list, int pos );
162a_Exp new_exp_from_func_call( a_Exp base, a_Exp args, int pos );
163a_Exp new_exp_from_member_dot( a_Exp base, c_str member, int pos );
164a_Exp new_exp_from_postfix( a_Exp base, ae_Operator op, int pos );
165a_Exp new_exp_from_dur( a_Exp base, a_Exp unit, int pos );
166a_Exp new_exp_from_id( c_str xid, int pos );
167a_Exp new_exp_from_int( long num, int pos );
168a_Exp new_exp_from_uint( unsigned long num, int pos );
169a_Exp new_exp_from_float( double num, int pos );
170a_Exp new_exp_from_str( c_str str, int pos );
171a_Exp new_exp_from_char( c_str chr, int pos );
172a_Exp new_exp_from_if( a_Exp cond, a_Exp lhs, a_Exp rhs, int pos );
173a_Exp new_exp_from_complex( a_Complex, int pos );
174a_Exp new_exp_from_polar( a_Polar, int pos );
175a_Exp new_exp_from_vec( a_Vec, int pos ); // ge: added 1.3.5.3
176a_Exp new_exp_decl_external( a_Type_Decl type_decl, a_Var_Decl_List var_decl_list, int is_static, int pos );
177a_Exp new_exp_decl( a_Type_Decl type_decl, a_Var_Decl_List var_decl_list, int is_static, int pos );
178a_Exp new_exp_from_hack( a_Exp exp, int pos );
179a_Exp new_exp_from_nil( int pos );
180a_Var_Decl_List new_var_decl_list( a_Var_Decl var_decl, int pos );
181a_Var_Decl_List prepend_var_decl_list( a_Var_Decl var_decl, a_Var_Decl_List list, int pos );
182a_Var_Decl new_var_decl( c_constr xid, a_Array_Sub array, int pos );
183a_Type_Decl new_type_decl( a_Id_List xid, int ref, int pos );
184a_Type_Decl add_type_decl_array( a_Type_Decl type_decl, a_Array_Sub array, int pos );
185a_Arg_List new_arg_list( a_Type_Decl type_decl, a_Var_Decl var_decl, int pos );
186a_Arg_List prepend_arg_list( a_Type_Decl type_decl, a_Var_Decl var_decl, a_Arg_List arg_list, int pos );
187a_Array_Sub new_array_sub( a_Exp exp, int pos );
188a_Array_Sub prepend_array_sub( a_Array_Sub array, a_Exp exp, int pos );
189a_Complex new_complex( a_Exp re, int pos );
190a_Polar new_polar( a_Exp mod, int pos ); // ge: added 1.3.5.3
191a_Vec new_vec( a_Exp e, int pos );
192
193a_Class_Def new_class_def( ae_Keyword class_decl, a_Id_List xid, a_Class_Ext ext, a_Class_Body body, int pos );
194a_Class_Body new_class_body( a_Section section, int pos );
195a_Class_Body prepend_class_body( a_Section section, a_Class_Body body, int pos );
196a_Class_Ext new_class_ext( a_Id_List extend_id, a_Id_List impl_list, int pos );
197a_Class_Def new_iface_def( ae_Keyword class_decl, a_Id_List xid, a_Class_Ext ext, a_Class_Body body, int pos );
198a_Id_List new_id_list( c_constr xid, int pos );
199a_Id_List prepend_id_list( c_constr xid, a_Id_List list, int pos );
200void clean_exp( a_Exp exp );
201a_Func_Def new_func_def( ae_Keyword func_decl, ae_Keyword static_decl,
202 a_Type_Decl type_decl, c_str name,
203 a_Arg_List arg_list, a_Stmt code, int pos );
204
205void delete_id_list( a_Id_List x );
206
207
208
209
210//------------------------------------------------------------------------------
211// structs
212//------------------------------------------------------------------------------
213struct a_Exp_Binary_ { a_Exp lhs; ae_Operator op; a_Exp rhs; t_CKFUNC ck_func; int linepos; a_Exp self; };
214struct a_Exp_Cast_ { a_Type_Decl type; a_Exp exp; int linepos; a_Exp self; };
215struct a_Exp_Unary_ { ae_Operator op; a_Exp exp; a_Type_Decl type; a_Array_Sub array;
216 a_Stmt code; int linepos; a_Exp self; };
217struct a_Exp_Postfix_ { a_Exp exp; ae_Operator op; int linepos; a_Exp self; };
218struct a_Exp_Dur_ { a_Exp base; a_Exp unit; int linepos; a_Exp self; };
219struct a_Exp_Array_ { a_Exp base; a_Array_Sub indices; int linepos; a_Exp self; };
220struct a_Exp_Func_Call_ { a_Exp func; a_Exp args; t_CKTYPE ret_type;
221 t_CKFUNC ck_func; t_CKVMCODE ck_vm_code; int linepos; a_Exp self; };
222struct a_Exp_Dot_Member_ { a_Exp base; t_CKTYPE t_base; S_Symbol xid; int linepos; a_Exp self; };
223struct a_Exp_If_ { a_Exp cond; a_Exp if_exp; a_Exp else_exp; int linepos; a_Exp self; };
224struct a_Exp_Decl_ { a_Type_Decl type; a_Var_Decl_List var_decl_list; int num_var_decls; int is_static; int is_external;
225 t_CKTYPE ck_type; int linepos; a_Exp self; };
226struct a_Exp_Hack_ { a_Exp exp; int linepos; a_Exp self; };
227struct a_Var_Decl_List_ { a_Var_Decl var_decl; a_Var_Decl_List next; int linepos; a_Exp self; };
228struct a_Var_Decl_ { S_Symbol xid; a_Var_Decl var_decl; a_Array_Sub array; t_CKVALUE value;
229 void * addr; int linepos; a_Exp self; };
230struct a_Type_Decl_ { a_Id_List xid; a_Array_Sub array; int ref; int linepos; /*a_Exp self;*/ };
231struct a_Array_Sub_ { t_CKUINT depth; a_Exp exp_list; int linepos; a_Exp self;
232 int err_num; int err_pos; };
233struct a_Arg_List_ { a_Type_Decl type_decl; a_Var_Decl var_decl; t_CKTYPE type;
234 a_Arg_List next; int linepos; a_Exp self; };
235struct a_Complex_ { a_Exp re; a_Exp im; int linepos; a_Exp self; };
236struct a_Polar_ { a_Exp mod; a_Exp phase; int linepos; a_Exp self; };
237struct a_Vec_ { a_Exp args; int numdims; int linepos; a_Exp self; }; // ge: added 1.3.5.3
238
239// enum primary exp type
240typedef enum { ae_primary_var, ae_primary_num, ae_primary_float,
241 ae_primary_str, ae_primary_array, ae_primary_exp,
242 ae_primary_hack, ae_primary_complex, ae_primary_polar,
243 ae_primary_vec, ae_primary_char, ae_primary_nil
244 } ae_Exp_Primary_Type;
245
246struct a_Exp_Primary_
247{
248 ae_Exp_Primary_Type s_type;
249 t_CKVALUE value;
250
251 union
252 {
253 S_Symbol var;
254 t_CKINT num;
255 t_CKFLOAT fnum;
256 c_str str;
257 c_str chr;
258 a_Array_Sub array;
259 a_Exp exp;
260 a_Complex complex;
261 a_Polar polar;
262 a_Vec vec; // ge: added 1.3.5.3
263 };
264
265 int linepos;
266 a_Exp self;
267};
268
269// enum exp type
270typedef enum { ae_exp_binary = 0, ae_exp_unary, ae_exp_cast, ae_exp_postfix,
271 ae_exp_dur, ae_exp_primary, ae_exp_array, ae_exp_func_call,
272 ae_exp_dot_member, ae_exp_if, ae_exp_decl
273 } ae_Exp_Type;
274// type meta data
275typedef enum { ae_meta_value = 0, ae_meta_var } ae_Exp_Meta;
276
277struct a_Exp_
278{
279 ae_Exp_Type s_type;
280 ae_Exp_Meta s_meta;
281 t_CKTYPE type;
282 t_CKNSPC owner;
283 a_Exp next;
284
285 t_CKUINT group_size;
286 t_CKTYPE cast_to;
287 t_CKUINT emit_var; // 1 = emit var, 2 = emit var and value
288
289 union
290 {
291 struct a_Exp_Binary_ binary;
292 struct a_Exp_Unary_ unary;
293 struct a_Exp_Cast_ cast;
294 struct a_Exp_Postfix_ postfix;
295 struct a_Exp_Dur_ dur;
296 struct a_Exp_Primary_ primary;
297 struct a_Exp_Array_ array;
298 struct a_Exp_Func_Call_ func_call;
299 struct a_Exp_Dot_Member_ dot_member;
300 struct a_Exp_If_ exp_if;
301 struct a_Exp_Decl_ decl;
302 };
303
304 int linepos;
305};
306
307struct a_Stmt_While_ { int is_do; a_Exp cond; a_Stmt body; int linepos; a_Stmt self; };
308struct a_Stmt_Until_ { int is_do; a_Exp cond; a_Stmt body; int linepos; a_Stmt self; };
309struct a_Stmt_For_ { a_Stmt c1; a_Stmt c2; a_Exp c3; a_Stmt body; int linepos; a_Stmt self; };
310struct a_Stmt_Loop_ { a_Exp cond; a_Stmt body; int linepos; a_Stmt self; };
311struct a_Stmt_Code_ { a_Stmt_List stmt_list; int linepos; a_Stmt self; };
312struct a_Stmt_If_ { a_Exp cond; a_Stmt if_body; a_Stmt else_body; int linepos; a_Stmt self; };
313struct a_Stmt_Switch_ { a_Exp val; int linepos; a_Stmt self; };
314struct a_Stmt_Break_ { int linepos; a_Stmt self; };
315struct a_Stmt_Continue_ { int linepos; a_Stmt self; };
316struct a_Stmt_Return_ { a_Exp val; int linepos; a_Stmt self; };
317struct a_Stmt_Case_ { a_Exp exp; int linepos; a_Stmt self; };
318struct a_Stmt_GotoLabel_ { S_Symbol name; int linepos; a_Stmt self; };
319
320// enum values for stmt type
321typedef enum { ae_stmt_exp, ae_stmt_while, ae_stmt_until, ae_stmt_for, ae_stmt_loop,
322 ae_stmt_if, ae_stmt_code, ae_stmt_switch, ae_stmt_break,
323 ae_stmt_continue, ae_stmt_return, ae_stmt_case, ae_stmt_gotolabel
324 } ae_Stmt_Type;
325
326struct a_Stmt_
327{
328 ae_Stmt_Type s_type;
329 int skip;
330
331 union
332 {
333 a_Exp stmt_exp;
334 struct a_Stmt_Code_ stmt_code;
335 struct a_Stmt_While_ stmt_while;
336 struct a_Stmt_Until_ stmt_until;
337 struct a_Stmt_Loop_ stmt_loop;
338 struct a_Stmt_For_ stmt_for;
339 struct a_Stmt_If_ stmt_if;
340 struct a_Stmt_Switch_ stmt_switch;
341 struct a_Stmt_Break_ stmt_break;
342 struct a_Stmt_Continue_ stmt_continue;
343 struct a_Stmt_Return_ stmt_return;
344 struct a_Stmt_Case_ stmt_case;
345 struct a_Stmt_GotoLabel_ stmt_gotolabel;
346 };
347
348 int linepos;
349};
350
351struct a_Stmt_List_ { a_Stmt stmt; a_Stmt_List next; int linepos; };
352struct a_Class_Def_ { ae_Keyword decl; a_Id_List name; a_Class_Ext ext;
353 a_Class_Body body; t_CKTYPE type; int iface; t_CKNSPC home;
354 int linepos; };
355struct a_Class_Ext_ { a_Id_List extend_id; a_Id_List impl_list; int linepos; };
356struct a_Class_Body_ { a_Section section; a_Class_Body next; int linepos; };
357struct a_Id_List_ { S_Symbol xid; a_Id_List next; int linepos; };
358
359typedef enum { ae_func_user, ae_func_builtin } ae_Func_Type;
360// struct t_Func_User_ { int linepos; };
361// typedef unsigned int (* builtin_func_ptr)( unsigned int arg );
362// struct t_Func_BuiltIn_ { builtin_func_ptr func_ptr; int linepos; };
363struct a_Func_Def_ {
364 ae_Keyword func_decl;
365 ae_Keyword static_decl;
366 a_Type_Decl type_decl;
367 t_CKTYPE ret_type;
368 S_Symbol name;
369 a_Arg_List arg_list;
370 a_Stmt code;
371 t_CKFUNC ck_func;
372 unsigned int global;
373 unsigned int s_type;
374 unsigned int stack_depth;
375 void * dl_func_ptr; // should be not NULL iff s_type == ae_func_builtin
376 int linepos;
377};
378
379// enum values for section types
380typedef enum { ae_section_stmt, ae_section_func, ae_section_class
381 } ae_Section_Type;
382
383struct a_Section_
384{
385 ae_Section_Type s_type;
386
387 union
388 {
389 a_Stmt_List stmt_list;
390 a_Class_Def class_def;
391 a_Func_Def func_def;
392 };
393
394 int linepos;
395};
396
397struct a_Program_ { a_Section section; a_Program next; int linepos; };
398
399
400#if defined(_cplusplus) || defined(__cplusplus)
401}
402#endif
403
404
405
406#endif
core/chuck_carrier.h+0−94
@@ -1,94 +0,0 @@
1/*----------------------------------------------------------------------------
2 ChucK Concurrent, On-the-fly Audio Programming Language
3 Compiler and Virtual Machine
4
5 Copyright (c) 2003 Ge Wang and Perry R. Cook. All rights reserved.
6 http://chuck.stanford.edu/
7 http://chuck.cs.princeton.edu/
8
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.
13
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.
18
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 -----------------------------------------------------------------------------*/
24
25//-----------------------------------------------------------------------------
26// file: chuck_carrier.h
27// desc: carrier of things associated with each ChucK instance
28// REFACTOR-2017
29//
30// author: Ge Wang (http://www.gewang.com/)
31// Jack Atherton (lja@ccrma.stanford.edu)
32// date: fall 2017
33//
34// additional authors:
35// Spencer Salazar (spencer@ccrma.stanford.edu)
36//-----------------------------------------------------------------------------
37#ifndef __CHUCK_CARRIER_H__
38#define __CHUCK_CARRIER_H__
39
40#include "chuck_def.h"
41#include "util_thread.h"
42
43
44
45
46// forward references (C++)
47class Chuck_Compiler;
48class Chuck_VM;
49class Chuck_Env;
50class Chuck_IO_Chout;
51class Chuck_IO_Cherr;
52
53// forward references ("C")
54struct ck_socket_;
55typedef struct ck_socket_ * ck_socket;
56
57
58
59
60
61//-----------------------------------------------------------------------------
62// name: struct Chuck_Carrier
63// desc: carrier of per-ChucK-instance things; each
64//-----------------------------------------------------------------------------
65struct Chuck_Carrier
66{
67 Chuck_Compiler * compiler;
68 Chuck_Env * env;
69 Chuck_VM * vm;
70 Chuck_IO_Chout * chout;
71 Chuck_IO_Cherr * cherr;
72
73 // OTF programming things
74 ck_socket otf_socket;
75 t_CKINT otf_port;
76 CHUCK_THREAD otf_thread;
77
78 // constructor
79 Chuck_Carrier() :
80 compiler( NULL ),
81 env( NULL ),
82 vm( NULL ),
83 chout( NULL ),
84 cherr( NULL ),
85 otf_socket( NULL ),
86 otf_port( 0 ),
87 otf_thread( 0 )
88 { }
89};
90
91
92
93
94#endif
core/chuck_compile.cpp+0−900
@@ -1,900 +0,0 @@
1/*----------------------------------------------------------------------------
2 ChucK Concurrent, On-the-fly Audio Programming Language
3 Compiler and Virtual Machine
4
5 Copyright (c) 2004 Ge Wang and Perry R. Cook. All rights reserved.
6 http://chuck.stanford.edu/
7 http://chuck.cs.princeton.edu/
8
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.
13
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.
18
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-----------------------------------------------------------------------------*/
24
25//-----------------------------------------------------------------------------
26// file: chuck_compile.cpp
27// desc: chuck compile system unifying parser, type checker, and emitter
28//
29// author: Ge Wang (ge@ccrma.stanford.edu | gewang@cs.princeton.edu)
30// date: Autumn 2005 - original
31//-----------------------------------------------------------------------------
32#include "chuck_compile.h"
33#include "chuck_lang.h"
34#include "chuck_errmsg.h"
35#include "chuck_otf.h"
36
37#include "ugen_osc.h"
38#include "ugen_xxx.h"
39#include "ugen_filter.h"
40#include "ugen_stk.h"
41#include "uana_xform.h"
42#include "uana_extract.h"
43#include "ulib_machine.h"
44#include "ulib_math.h"
45#include "ulib_std.h"
46#include "ulib_opsc.h"
47#include "ulib_regex.h"
48#include "chuck_io.h"
49
50#if defined(__PLATFORM_WIN32__)
51#include "dirent_win32.h"
52#endif
53//#if defined(__WINDOWS_PTHREAD__)
54#include <sys/stat.h>
55//#endif
56
57using namespace std;
58
59
60
61
62// function prototypes
63t_CKBOOL load_internal_modules( Chuck_Compiler * compiler );
64t_CKBOOL load_external_modules( Chuck_Compiler * compiler,
65 const char * extension,
66 std::list<std::string> & chugin_search_paths,
67 std::list<std::string> & named_dls);
68t_CKBOOL load_module( Chuck_Compiler * compiler, Chuck_Env * env, f_ck_query query, const char * name, const char * nspc );
69
70
71
72
73//-----------------------------------------------------------------------------
74// name: Chuck_Compiler()
75// desc: constructor
76//-----------------------------------------------------------------------------
77Chuck_Compiler::Chuck_Compiler()
78{
79 emitter = NULL;
80 code = NULL;
81
82 // REFACTOR-2017: add carrier
83 m_carrier = NULL;
84}
85
86
87
88
89//-----------------------------------------------------------------------------
90// name: ~Chuck_Compiler()
91// desc: destructor
92//-----------------------------------------------------------------------------
93Chuck_Compiler::~Chuck_Compiler()
94{
95 // call shutdown
96 this->shutdown();
97}
98
99
100
101
102//-----------------------------------------------------------------------------
103// name: initialize()
104// desc: initialize the compiler
105//-----------------------------------------------------------------------------
106t_CKBOOL Chuck_Compiler::initialize( std::list<std::string> & chugin_search_paths,
107 std::list<std::string> & named_dls )
108{
109 // log
110 EM_log( CK_LOG_SYSTEM, "initializing compiler..." );
111 // push indent level
112 EM_pushlog();
113
114 // allocate the type checker
115 Chuck_Env * env = type_engine_init( m_carrier );
116 // add reference
117 env->add_ref();
118
119 // allocate the emitter
120 emitter = emit_engine_init( env );
121 // add reference
122 emitter->add_ref();
123 // set auto depend to 0
124 m_auto_depend = FALSE;
125
126 // load internal libs
127 if( !load_internal_modules( this ) )
128 goto error;
129
130 // load external libs
131 if( !load_external_modules( this, ".chug", chugin_search_paths, named_dls ) )
132 goto error;
133
134 // pop indent
135 EM_poplog();
136
137 return TRUE;
138
139error:
140 // clean up
141 this->shutdown();
142
143 // pop indent
144 EM_poplog();
145
146 return FALSE;
147}
148
149
150
151
152//-----------------------------------------------------------------------------
153// name: shutdown()
154// desc: shutdown the compiler
155//-----------------------------------------------------------------------------
156void Chuck_Compiler::shutdown()
157{
158 // log
159 EM_log( CK_LOG_SYSTEM, "shutting down compiler..." ) ;
160 // push indent
161 EM_pushlog();
162
163 // TODO: free
164 type_engine_shutdown( env() );
165 // TODO: check if emitter gets cleaned up
166 // emit_engine_shutdown( emitter );
167 emitter = NULL;
168 code = NULL;
169 m_auto_depend = FALSE;
170 m_recent.clear();
171
172 for(std::list<Chuck_DLL *>::iterator i = m_dlls.begin();
173 i != m_dlls.end(); i++)
174 {
175 delete (*i);
176 }
177
178 m_dlls.clear();
179
180 // pop indent
181 EM_poplog();
182}
183
184
185
186
187
188//-----------------------------------------------------------------------------
189// name: bind()
190// desc: bind a new type system module, via query function
191//-----------------------------------------------------------------------------
192t_CKBOOL Chuck_Compiler::bind( f_ck_query query_func, const std::string & name,
193 const std::string & nspc )
194{
195 // log
196 EM_log( CK_LOG_SYSTEM, "on-demand binding compiler module '%s'...",
197 name.c_str() );
198 // push indent level
199 EM_pushlog();
200
201 // get env
202 Chuck_Env * env = this->env();
203 // make context
204 Chuck_Context * context = type_engine_make_context(
205 NULL, string("@[bind:") + name + string("]") );
206 // reset env - not needed since we just created the env
207 env->reset();
208 // load it
209 type_engine_load_context( env, context );
210
211 // do it
212 if( !load_module( this, env, query_func, name.c_str(), nspc.c_str() ) ) goto error;
213
214 // clear context
215 type_engine_unload_context( env );
216
217 // commit what is in the type checker at this point
218 env->global()->commit();
219
220 // pop indent level
221 EM_poplog();
222
223 return TRUE;
224
225error:
226
227 // probably dangerous: rollback
228 env->global()->rollback();
229
230 // clear context
231 type_engine_unload_context( env );
232
233 // pop indent level
234 EM_poplog();
235
236 return FALSE;
237}
238
239
240
241
242//-----------------------------------------------------------------------------
243// name: set_auto_depend()
244// desc: auto dependency resolve for types
245//-----------------------------------------------------------------------------
246void Chuck_Compiler::set_auto_depend( t_CKBOOL v )
247{
248 // log
249 EM_log( CK_LOG_SYSTEM, "type dependency resolution: %s",
250 v ? "AUTO" : "MANUAL" );
251 m_auto_depend = v;
252}
253
254
255
256
257//-----------------------------------------------------------------------------
258// name: go()
259// desc: parse, type-check, and emit a program
260//-----------------------------------------------------------------------------
261t_CKBOOL Chuck_Compiler::go( const string & filename, FILE * fd, const char * str_src, const string & full_path )
262{
263 t_CKBOOL ret = TRUE;
264 Chuck_Context * context = NULL;
265
266 EM_reset_msg();
267
268 // check to see if resolve dependencies automatically
269 if( !m_auto_depend )
270 {
271 // normal (note: full_path added 1.3.0.0)
272 ret = this->do_normal( filename, fd, str_src, full_path );
273 return ret;
274 }
275 else // auto
276 {
277 // parse the code
278 if( !chuck_parse( filename.c_str(), fd, str_src ) )
279 return FALSE;
280
281 // make the context
282 context = type_engine_make_context( g_program, filename );
283 if( !context ) return FALSE;
284
285 // reset the env
286 env()->reset();
287
288 // load the context
289 if( !type_engine_load_context( env(), context ) )
290 return FALSE;
291
292 // do entire file
293 if( !do_entire_file( context ) )
294 { ret = FALSE; goto cleanup; }
295
296 // get the code
297 if( !(code = context->code()) )
298 {
299 ret = FALSE;
300 EM_error2( 0, "internal error: context->code() NULL!" );
301 goto cleanup;
302 }
303
304cleanup:
305
306 // commit
307 if( ret ) env()->global()->commit();
308 // or rollback
309 else env()->global()->rollback();
310
311 // unload the context from the type-checker
312 if( !type_engine_unload_context( env() ) )
313 {
314 EM_error2( 0, "internal error unloading context...\n" );
315 return FALSE;
316 }
317
318 return ret;
319 }
320}
321
322
323
324
325//-----------------------------------------------------------------------------
326// name: resolve()
327// desc: resolve type automatically - if auto_depend is off, return FALSE
328//-----------------------------------------------------------------------------
329t_CKBOOL Chuck_Compiler::resolve( const string & type )
330{
331 t_CKBOOL ret = TRUE;
332
333 // check auto_depend
334 if( !m_auto_depend )
335 return FALSE;
336
337 // look up if name is already parsed
338
339
340
341 return ret;
342}
343
344
345
346
347//-----------------------------------------------------------------------------
348// name: do_entire_file()
349// desc: parse, type-check, and emit a program
350//-----------------------------------------------------------------------------
351t_CKBOOL Chuck_Compiler::do_entire_file( Chuck_Context * context )
352{
353 // 0th-scan (pass 0)
354 if( !type_engine_scan0_prog( env(), g_program, te_do_all ) )
355 return FALSE;
356
357 // 1st-scan (pass 1)
358 if( !type_engine_scan1_prog( env(), g_program, te_do_all ) )
359 return FALSE;
360
361 // 2nd-scan (pass 2)
362 if( !type_engine_scan2_prog( env(), g_program, te_do_all ) )
363 return FALSE;
364
365 // check the program (pass 3)
366 if( !type_engine_check_context( env(), context, te_do_all ) )
367 return FALSE;
368
369 // emit (pass 4)
370 if( !emit_engine_emit_prog( emitter, g_program ) )
371 return FALSE;
372
373 // set the state of the context to done
374 context->progress = Chuck_Context::P_ALL;
375
376 return TRUE;
377}
378
379
380
381
382//-----------------------------------------------------------------------------
383// name: do_only_classes()
384// desc: compile only classes definitions
385//-----------------------------------------------------------------------------
386t_CKBOOL Chuck_Compiler::do_only_classes( Chuck_Context * context )
387{
388 // 0th-scan (pass 0)
389 if( !type_engine_scan0_prog( env(), g_program, te_do_classes_only ) )
390 return FALSE;
391
392 // 1st-scan (pass 1)
393 if( !type_engine_scan1_prog( env(), g_program, te_do_classes_only ) )
394 return FALSE;
395
396 // 2nd-scan (pass 2)
397 if( !type_engine_scan2_prog( env(), g_program, te_do_classes_only ) )
398 return FALSE;
399
400 // check the program (pass 3)
401 if( !type_engine_check_context( env(), context, te_do_classes_only ) )
402 return FALSE;
403
404 // emit (pass 4)
405 if( !(code = emit_engine_emit_prog( emitter, g_program , te_do_classes_only )) )
406 return FALSE;
407
408 // set the state of the context to done
409 context->progress = Chuck_Context::P_ALL;
410
411 return TRUE;
412}
413
414
415
416
417//-----------------------------------------------------------------------------
418// name: do_all_except_classes()
419// desc: compile everything except classes
420//-----------------------------------------------------------------------------
421t_CKBOOL Chuck_Compiler::do_all_except_classes( Chuck_Context * context )
422{
423 // 0th scan only deals with classes, so is not needed
424
425 // 1st-scan (pass 1)
426 if( !type_engine_scan1_prog( env(), g_program, te_do_no_classes ) )
427 return FALSE;
428
429 // 2nd-scan (pass 2)
430 if( !type_engine_scan2_prog( env(), g_program, te_do_no_classes ) )
431 return FALSE;
432
433 // check the program (pass 3)
434 if( !type_engine_check_context( env(), context, te_do_no_classes ) )
435 return FALSE;
436
437 // emit (pass 4)
438 if( !(code = emit_engine_emit_prog( emitter, g_program, te_do_no_classes )) )
439 return FALSE;
440
441 // set the state of the context to done
442 context->progress = Chuck_Context::P_ALL;
443
444 return TRUE;
445}
446
447
448
449
450//-----------------------------------------------------------------------------
451// name: do_normal()
452// desc: compile normally without auto-depend
453//-----------------------------------------------------------------------------
454t_CKBOOL Chuck_Compiler::do_normal( const string & filename, FILE * fd, const char * str_src, const string & full_path )
455{
456 t_CKBOOL ret = TRUE;
457 Chuck_Context * context = NULL;
458
459 // parse the code
460 if( !chuck_parse( filename.c_str(), fd, str_src ) )
461 return FALSE;
462
463 // make the context
464 context = type_engine_make_context( g_program, filename );
465 if( !context ) return FALSE;
466
467 // remember full path (added 1.3.0.0)
468 context->full_path = full_path;
469
470 // reset the env
471 env()->reset();
472
473 // load the context
474 if( !type_engine_load_context( env(), context ) )
475 return FALSE;
476
477 // 0th-scan (pass 0)
478 if( !type_engine_scan0_prog( env(), g_program, te_do_all ) )
479 { ret = FALSE; goto cleanup; }
480
481 // 1st-scan (pass 1)
482 if( !type_engine_scan1_prog( env(), g_program, te_do_all ) )
483 { ret = FALSE; goto cleanup; }
484
485 // 2nd-scan (pass 2)
486 if( !type_engine_scan2_prog( env(), g_program, te_do_all ) )
487 { ret = FALSE; goto cleanup; }
488
489 // check the program (pass 3)
490 if( !type_engine_check_context( env(), context, te_do_all ) )
491 { ret = FALSE; goto cleanup; }
492
493 // emit (pass 4)
494 if( !(code = emit_engine_emit_prog( emitter, g_program, te_do_all )) )
495 { ret = FALSE; goto cleanup; }
496
497cleanup:
498
499 // commit
500 if( ret ) env()->global()->commit();
501 // or rollback
502 else env()->global()->rollback();
503
504 // unload the context from the type-checker
505 if( !type_engine_unload_context( env() ) )
506 {
507 EM_error2( 0, "internal error unloading context...\n" );
508 return FALSE;
509 }
510
511 return ret;
512}
513
514
515
516
517//-----------------------------------------------------------------------------
518// name: find_recent_path()
519// desc: find recent context by path
520//-----------------------------------------------------------------------------
521Chuck_Context * Chuck_Compiler::find_recent_path( const string & path )
522{
523 return NULL;
524}
525
526
527
528
529//-----------------------------------------------------------------------------
530// name: find_recent_type()
531// desc: find recent context by type name
532//-----------------------------------------------------------------------------
533Chuck_Context * Chuck_Compiler::find_recent_type( const string & type )
534{
535 return NULL;
536}
537
538
539
540
541//-----------------------------------------------------------------------------
542// name: add_recent_path()
543// desc: add recent context by path
544//-----------------------------------------------------------------------------
545t_CKBOOL Chuck_Compiler::add_recent_path( const string & path,
546 Chuck_Context * context )
547{
548 return TRUE;
549}
550
551
552
553
554//-----------------------------------------------------------------------------
555// name: output()
556// desc: get the code generated by the last do()
557//-----------------------------------------------------------------------------
558Chuck_VM_Code * Chuck_Compiler::output()
559{
560 return this->code;
561}
562
563
564
565
566//-----------------------------------------------------------------------------
567// name: load_module()
568// desc: load a dll and add it
569//-----------------------------------------------------------------------------
570t_CKBOOL load_module( Chuck_Compiler * compiler, Chuck_Env * env, f_ck_query query,
571 const char * name, const char * nspc )
572{
573 Chuck_DLL * dll = NULL;
574 t_CKBOOL query_failed = FALSE;
575
576 // load osc
577 dll = new Chuck_DLL( compiler->carrier(), name );
578 // (fixed: 1.3.0.0) query_failed now catches either failure of load or query
579 if( (query_failed = !(dll->load( query ) && dll->query())) ||
580 !type_engine_add_dll( env, dll, nspc ) )
581 {
582 CK_FPRINTF_STDERR(
583 "[chuck]: internal error loading module '%s.%s'...\n",
584 nspc, name );
585 if( query_failed )
586 CK_FPRINTF_STDERR( " %s", dll->last_error() );
587
588 return FALSE;
589 }
590
591 return TRUE;
592}
593
594
595
596
597//-----------------------------------------------------------------------------
598// name: load_internal_modules()
599// desc: ...
600//-----------------------------------------------------------------------------
601t_CKBOOL load_internal_modules( Chuck_Compiler * compiler )
602{
603 // log
604 EM_log( CK_LOG_SEVERE, "loading built-in modules..." );
605 // push indent level
606 EM_pushlog();
607
608 // get env
609 Chuck_Env * env = compiler->env();
610 // make context
611 Chuck_Context * context = type_engine_make_context( NULL, "@[internal]" );
612 // reset env - not needed since we just created the env
613 env->reset();
614 // load it
615 type_engine_load_context( env, context );
616
617//#ifndef __DISABLE_MIDI__
618 if( !init_class_Midi( env ) ) goto error;
619 if( !init_class_MidiRW( env ) ) goto error;
620//#endif // __DISABLE_MIDI__
621
622 // load
623 EM_log( CK_LOG_SEVERE, "module osc..." );
624 load_module( compiler, env, osc_query, "osc", "global" );
625 EM_log( CK_LOG_SEVERE, "module xxx..." );
626 load_module( compiler, env, xxx_query, "xxx", "global" );
627 EM_log( CK_LOG_SEVERE, "module filter..." );
628 load_module( compiler, env, filter_query, "filter", "global" );
629 EM_log( CK_LOG_SEVERE, "module STK..." );
630 load_module( compiler, env, stk_query, "stk", "global" );
631 EM_log( CK_LOG_SEVERE, "module xform..." );
632 load_module( compiler, env, xform_query, "xform", "global" );
633 EM_log( CK_LOG_SEVERE, "module extract..." );
634 load_module( compiler, env, extract_query, "extract", "global" );
635
636 // load
637 EM_log( CK_LOG_SEVERE, "class 'machine'..." );
638 if( !load_module( compiler, env, machine_query, "Machine", "global" ) ) goto error;
639 machine_init( compiler, otf_process_msg );
640 EM_log( CK_LOG_SEVERE, "class 'std'..." );
641 if( !load_module( compiler, env, libstd_query, "Std", "global" ) ) goto error;
642 EM_log( CK_LOG_SEVERE, "class 'math'..." );
643 if( !load_module( compiler, env, libmath_query, "Math", "global" ) ) goto error;
644
645// ge: these currently don't compile on "modern" windows versions (1.3.5.3)
646#ifndef __WINDOWS_MODERN__
647 EM_log( CK_LOG_SEVERE, "class 'opsc'..." );
648 if( !load_module( compiler, env, opensoundcontrol_query, "opsc", "global" ) ) goto error;
649#endif
650 EM_log( CK_LOG_SEVERE, "class 'RegEx'..." );
651 if( !load_module( compiler, env, regex_query, "RegEx", "global" ) ) goto error;
652 // if( !load_module( compiler, env, net_query, "net", "global" ) ) goto error;
653
654 if( !init_class_HID( env ) ) goto error;
655 if( !init_class_serialio( env ) ) goto error;
656
657 // clear context
658 type_engine_unload_context( env );
659
660 // commit what is in the type checker at this point
661 env->global()->commit();
662
663 // pop indent level
664 EM_poplog();
665
666 return TRUE;
667
668error:
669
670 // probably dangerous: rollback
671 env->global()->rollback();
672
673 // clear context
674 type_engine_unload_context( env );
675
676 // pop indent level
677 EM_poplog();
678
679 return FALSE;
680}
681
682
683
684//-----------------------------------------------------------------------------
685// name: load_external_module_at_path()
686// desc: ...
687//-----------------------------------------------------------------------------
688t_CKBOOL load_external_module_at_path( Chuck_Compiler * compiler,
689 const char * name,
690 const char * dl_path )
691{
692 Chuck_Env * env = compiler->env();
693
694 EM_log(CK_LOG_SEVERE, "loading chugin '%s'", name);
695
696 Chuck_DLL * dll = new Chuck_DLL( compiler->carrier(), name );
697 t_CKBOOL query_failed = FALSE;
698
699 if((query_failed = !(dll->load(dl_path) && dll->query())) ||
700 !type_engine_add_dll2(env, dll, "global"))
701 {
702 EM_log(CK_LOG_SEVERE, "error loading chugin '%s', skipping", name);
703 if(query_failed)
704 EM_log(CK_LOG_SEVERE, "error from chuck_dl: '%s'", dll->last_error());
705 delete dll;
706
707 return FALSE;
708 }
709 else
710 {
711 compiler->m_dlls.push_back(dll);
712 return TRUE;
713 }
714}
715
716
717
718
719//-----------------------------------------------------------------------------
720// name: extension_matches()
721// desc: ...
722//-----------------------------------------------------------------------------
723static t_CKBOOL extension_matches( const char * filename, const char * extension )
724{
725 t_CKUINT extension_length = strlen(extension);
726 t_CKUINT filename_length = strlen(filename);
727
728 return strncmp( extension, filename+(filename_length-extension_length),
729 extension_length) == 0;
730}
731
732
733
734
735//-----------------------------------------------------------------------------
736// name: load_external_modules_in_directory()
737// desc: ...
738//-----------------------------------------------------------------------------
739t_CKBOOL load_external_modules_in_directory( Chuck_Compiler * compiler,
740 const char * directory,
741 const char * extension )
742{
743 static const t_CKBOOL RECURSIVE_SEARCH = false;
744
745 DIR * dir = opendir(directory);
746
747 if( dir )
748 {
749 // log
750 EM_log( CK_LOG_INFO, "examining directory '%s' for chugins", directory );
751
752 struct dirent *de = NULL;
753
754 while( (de = readdir(dir)) )
755 {
756 t_CKBOOL is_regular = false;
757 t_CKBOOL is_directory = false;
758
759#if defined(__PLATFORM_WIN32__)
760 is_directory = de->data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY;
761 is_regular = ((de->data.dwFileAttributes & FILE_ATTRIBUTE_NORMAL) ||
762 (de->data.dwFileAttributes & FILE_ATTRIBUTE_READONLY) ||
763 (de->data.dwFileAttributes & FILE_ATTRIBUTE_ARCHIVE));
764#elif defined(__WINDOWS_PTHREAD__) // Cygwin -- doesn't have dirent d_type
765 std::string absolute_path = std::string(directory) + "/" + de->d_name;
766 struct stat st;
767 if( stat(absolute_path.c_str(), &st) == 0 )
768 {
769 is_directory = st.st_mode & S_IFDIR;
770 is_regular = st.st_mode & S_IFREG;
771 }
772 else
773 {
774 // uhh ...
775 EM_log( CK_LOG_INFO,
776 "unable to stat file '%s', ignoring for chugins",
777 absolute_path.c_str() );
778 continue;
779 }
780#else
781 is_directory = de->d_type == DT_DIR;
782 is_regular = de->d_type == DT_REG;
783#endif
784
785 if( is_regular ) // TODO: follow links?
786 {
787 if( extension_matches(de->d_name, extension) )
788 {
789 std::string absolute_path = std::string(directory) + "/" + de->d_name;
790
791 load_external_module_at_path(compiler, de->d_name,
792 absolute_path.c_str());
793 }
794 else if( extension_matches(de->d_name, ".ck") )
795 {
796 std::string absolute_path = std::string(directory) + "/" + de->d_name;
797 compiler->m_cklibs_to_preload.push_back(absolute_path);
798 }
799 }
800 else if( RECURSIVE_SEARCH && is_directory )
801 {
802 // recurse
803 // TODO: max depth?
804 if( strncmp(de->d_name, ".", sizeof(".")) != 0 &&
805 strncmp(de->d_name, "..", sizeof("..")) != 0 )
806 {
807 std::string absolute_path = std::string(directory) + "/" + de->d_name;
808 load_external_modules_in_directory(compiler,
809 absolute_path.c_str(),
810 extension);
811 }
812 }
813 }
814
815 // close
816 closedir( dir );
817 }
818 else
819 {
820 // log (1.3.1.2: changed to 2 lines to stay within 80 chars)
821 EM_log( CK_LOG_INFO, "unable to open directory '%s'...", directory );
822 EM_log( CK_LOG_INFO, "(ignoring for chugins...)" );
823 }
824
825 return TRUE;
826}
827
828
829
830
831//-----------------------------------------------------------------------------
832// name: load_external_modules()
833// desc: ...
834//-----------------------------------------------------------------------------
835t_CKBOOL load_external_modules( Chuck_Compiler * compiler,
836 const char * extension,
837 std::list<std::string> & chugin_search_paths,
838 std::list<std::string> & named_dls )
839{
840 // log
841 EM_log( CK_LOG_SEVERE, "loading chugins" );
842 // push indent level
843 EM_pushlog();
844
845 // get env
846 Chuck_Env * env = compiler->env();
847 // make context
848 Chuck_Context * context = type_engine_make_context( NULL, "@[external]" );
849 // reset env - not needed since we just created the env
850 env->reset();
851 // load it
852 type_engine_load_context( env, context );
853
854 /* first load dynamic libraries explicitly named on the command line */
855
856 for(std::list<std::string>::iterator i_dl = named_dls.begin();
857 i_dl != named_dls.end(); i_dl++)
858 {
859 std::string & dl_path = *i_dl;
860 if(!extension_matches(dl_path.c_str(), extension))
861 dl_path += extension;
862
863 load_external_module_at_path(compiler, dl_path.c_str(),
864 dl_path.c_str());
865 }
866
867 /* now recurse through search paths and load any DLs or .ck files found */
868
869 for(std::list<std::string>::iterator i_sp = chugin_search_paths.begin();
870 i_sp != chugin_search_paths.end(); i_sp++)
871 {
872 load_external_modules_in_directory(compiler, (*i_sp).c_str(), extension);
873 }
874
875 // clear context
876 type_engine_unload_context( env );
877
878 // commit what is in the type checker at this point
879 env->global()->commit();
880
881 // pop indent level
882 EM_poplog();
883
884 return TRUE;
885 /*
886error:
887
888 // probably dangerous: rollback
889 env->global()->rollback();
890
891 // clear context
892 type_engine_unload_context( env );
893
894 // pop indent level
895 EM_poplog();
896
897 return FALSE;
898 */
899}
900
core/chuck_compile.h+0−138
@@ -1,138 +0,0 @@
1/*----------------------------------------------------------------------------
2 ChucK Concurrent, On-the-fly Audio Programming Language
3 Compiler and Virtual Machine
4
5 Copyright (c) 2004 Ge Wang and Perry R. Cook. All rights reserved.
6 http://chuck.stanford.edu/
7 http://chuck.cs.princeton.edu/
8
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.
13
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.
18
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-----------------------------------------------------------------------------*/
24
25//-----------------------------------------------------------------------------
26// file: chuck_compile.h
27// desc: chuck compile system unifying parser, type checker, and emitter
28//
29// author: Ge Wang (ge@ccrma.stanford.edu | gewang@cs.princeton.edu)
30// date: Autumn 2005 - original
31//-----------------------------------------------------------------------------
32#ifndef __CHUCK_COMPILE_H__
33#define __CHUCK_COMPILE_H__
34
35#include "chuck_def.h"
36#include "chuck_parse.h"
37#include "chuck_scan.h"
38#include "chuck_type.h"
39#include "chuck_emit.h"
40#include "chuck_vm.h"
41#include <list>
42
43
44// forward reference
45struct Chuck_DLL;
46
47
48
49
50//-----------------------------------------------------------------------------
51// name: struct Chuck_Compiler
52// desc: the sum of the components in compilation
53//-----------------------------------------------------------------------------
54struct Chuck_Compiler
55{
56protected: // data
57 // carrier
58 Chuck_Carrier * m_carrier;
59
60public: // get protected data
61 // REFACTOR-2017: get associated, per-compiler environment
62 Chuck_Env * env() const { return m_carrier->env; }
63 // REFACTOR-2017: get associated, per-compiler VM
64 Chuck_VM * vm() const { return m_carrier->vm; }
65 // REFACTOR-2017: get associated, per-compiler carrier
66 Chuck_Carrier * carrier() const { return m_carrier; }
67 // set carrier
68 t_CKBOOL setCarrier( Chuck_Carrier * c ) { m_carrier = c; return TRUE; }
69
70
71public: // data
72 // emitter
73 Chuck_Emitter * emitter;
74 // generated code
75 Chuck_VM_Code * code;
76
77 // auto-depend flag
78 t_CKBOOL m_auto_depend;
79 // recent map
80 std::map<std::string, Chuck_Context *> m_recent;
81
82 std::list<Chuck_DLL *> m_dlls;
83 std::list<std::string> m_cklibs_to_preload;
84
85public: // to all
86 // contructor
87 Chuck_Compiler();
88 // destructor
89 virtual ~Chuck_Compiler();
90
91 // initialize
92 t_CKBOOL initialize( std::list<std::string> & chugin_search_paths,
93 std::list<std::string> & named_dls );
94 // shutdown
95 void shutdown();
96
97public: // additional binding
98 // bind a new type system module, via query function
99 t_CKBOOL bind( f_ck_query query_func, const std::string & name,
100 const std::string & nspc = "global" );
101
102public: // compile
103 // set auto depend
104 void set_auto_depend( t_CKBOOL v );
105 // parse, type-check, and emit a program
106 t_CKBOOL go( const std::string & filename, FILE * fd = NULL,
107 const char * str_src = NULL, const std::string & full_path = "" );
108 // resolve a type automatically, if auto_depend is on
109 t_CKBOOL resolve( const std::string & type );
110 // get the code generated from the last go()
111 Chuck_VM_Code * output( );
112
113protected: // internal
114 // do entire file
115 t_CKBOOL do_entire_file( Chuck_Context * context );
116 // do just class definitions
117 t_CKBOOL do_only_classes( Chuck_Context * context );
118 // do all excect classes
119 t_CKBOOL do_all_except_classes( Chuck_Context * context );
120 // do normal compile
121 t_CKBOOL do_normal( const std::string & path, FILE * fd = NULL,
122 const char * str_src = NULL, const std::string & full_path = "" );
123 // look up in recent
124 Chuck_Context * find_recent_path( const std::string & path );
125 // look up in recent
126 Chuck_Context * find_recent_type( const std::string & type );
127 // add to recent
128 t_CKBOOL add_recent_path( const std::string & path, Chuck_Context * context );
129};
130
131
132// call this to detach all open files
133extern "C" void all_detach();
134
135
136
137
138#endif
core/chuck_def.h+0−203
@@ -1,203 +0,0 @@
1/*----------------------------------------------------------------------------
2 ChucK Concurrent, On-the-fly Audio Programming Language
3 Compiler and Virtual Machine
4
5 Copyright (c) 2004 Ge Wang and Perry R. Cook. All rights reserved.
6 http://chuck.stanford.edu/
7 http://chuck.cs.princeton.edu/
8
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.
13
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.
18
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-----------------------------------------------------------------------------*/
24
25//-----------------------------------------------------------------------------
26// file: chuck_def.h
27// desc: ChucK defines for the system
28//
29// author: Ge Wang (ge@ccrma.stanford.edu | gewang@cs.princeton.edu)
30// Perry R. Cook (prc@cs.princeton.edu)
31// date: Autumn 2002
32//-----------------------------------------------------------------------------
33#ifndef __CHUCK_DEF_H__
34#define __CHUCK_DEF_H__
35
36#include <stdlib.h>
37#include <memory.h>
38#include <assert.h>
39
40
41// types
42#define t_CKTIME double
43#define t_CKDUR double
44#define t_CKFLOAT double
45#define t_CKDOUBLE double
46#define t_CKSINGLE float
47#ifdef _WIN64 // REFACTOR-2017
48#define t_CKINT long long // REFACTOR-2017
49#else
50#define t_CKINT long
51#endif
52#define t_CKUINT unsigned t_CKINT
53#define t_CKBOOL unsigned t_CKINT
54#define t_CKBYTE unsigned char
55#define t_CKVOID void
56#define t_CKVOIDPTR void *
57
58// complex type
59typedef struct { t_CKFLOAT re ; t_CKFLOAT im ; } t_CKCOMPLEX;
60// polar type
61typedef struct { t_CKFLOAT modulus ; t_CKFLOAT phase ; } t_CKPOLAR;
62
63// vector types
64typedef struct { t_CKFLOAT x ; t_CKFLOAT y ; t_CKFLOAT z ; } t_CKVEC3;
65typedef struct { t_CKFLOAT x ; t_CKFLOAT y ; t_CKFLOAT z ; t_CKFLOAT w ; } t_CKVEC4;
66typedef struct { t_CKUINT N ; t_CKFLOAT * values ; } t_CKVECTOR;
67
68// size
69#define sz_TIME sizeof(t_CKTIME)
70#define sz_DUR sizeof(t_CKDUR)
71#define sz_FLOAT sizeof(t_CKFLOAT)
72#define sz_DOUBLE sizeof(t_CKDOUBLE)
73#define sz_SINGLE sizeof(t_CKSINGLE)
74#define sz_INT sizeof(t_CKINT)
75#define sz_UINT sizeof(t_CKUINT)
76#define sz_BOOL sizeof(t_CKBOOL)
77#define sz_BYTE sizeof(t_CKBYTE)
78#define sz_VOIDPTR sizeof(t_CKVOIDPTR)
79#define sz_COMPLEX sizeof(t_CKCOMPLEX)
80#define sz_POLAR sizeof(t_CKPOLAR)
81#define sz_VEC3 sizeof(t_CKVEC3)
82#define sz_VEC4 sizeof(t_CKVEC4)
83#define sz_VECTOR sizeof(t_CKVECTOR)
84#define sz_VOID 0
85#define sz_WORD 4
86
87// kinds (added 1.3.1.0 to faciliate 64-bit support)
88// to differentiate in case int and float have same size
89#define kindof_VOID 0
90#define kindof_INT 1
91#define kindof_FLOAT 2
92#define kindof_COMPLEX 3
93#define kindof_VEC3 4
94#define kindof_VEC4 5
95
96typedef char * c_str;
97typedef const char * c_constr;
98
99// use 64-bit samples in the audio engine
100// #define __CHUCK_USE_64_BIT_SAMPLE__
101
102// sample
103#ifdef __CHUCK_USE_64_BIT_SAMPLE__
104#define SAMPLE double
105#define SILENCE 0.0
106#define CK_DDN CK_DDN_DOUBLE
107#else
108#define SAMPLE float
109#define SILENCE 0.0f
110#define CK_DDN CK_DDN_SINGLE
111#endif
112
113// for external use
114#define t_CKSAMPLE SAMPLE
115
116// sample complex
117typedef struct { SAMPLE re ; SAMPLE im ; } t_CKCOMPLEX_SAMPLE;
118
119// bool
120#ifndef TRUE
121#define TRUE 1
122#define FALSE 0
123#endif
124
125// 3.1415926535897932384626433832795028841971693993751058209749445...
126#define ONE_PI (3.14159265358979323846)
127#define TWO_PI (2.0 * ONE_PI)
128#define SQRT2 (1.41421356237309504880)
129
130#ifndef SAFE_DELETE
131#define SAFE_DELETE(x) do { if(x){ delete x; x = NULL; } } while(0)
132#define SAFE_DELETE_ARRAY(x) do { if(x){ delete [] x; x = NULL; } } while(0)
133#define SAFE_RELEASE(x) do { if(x){ x->release(); x = NULL; } } while(0)
134#define SAFE_ADD_REF(x) do { if(x){ x->add_ref(); } } while(0)
135#define SAFE_REF_ASSIGN(lhs,rhs) do { SAFE_RELEASE(lhs); (lhs) = (rhs); SAFE_ADD_REF(lhs); } while(0)
136#endif
137
138// max + min
139#define ck_max(x,y) ( (x) >= (y) ? (x) : (y) )
140#define ck_min(x,y) ( (x) <= (y) ? (x) : (y) )
141
142#ifndef __arm__
143// dedenormal
144#define CK_DDN_SINGLE(f) f = ( f >= 0 ? \
145 ( ( f > (t_CKSINGLE)1e-15 && f < (t_CKSINGLE)1e15 ) ? f : (t_CKSINGLE)0.0 ) : \
146 ( ( f < (t_CKSINGLE)-1e-15 && f > (t_CKSINGLE)-1e15 ) ? f : (t_CKSINGLE)0.0 ) )
147#define CK_DDN_DOUBLE(f) f = ( f >= 0 ? \
148 ( ( f > (t_CKDOUBLE)1e-15 && f < (t_CKDOUBLE)1e15 ) ? f : 0.0 ) : \
149 ( ( f < (t_CKDOUBLE)-1e-15 && f > (t_CKDOUBLE)-1e15 ) ? f : 0.0 ) )
150#else
151#define CK_DDN_SINGLE(f) (f)
152#define CK_DDN_DOUBLE(f) (f)
153#endif // __arm__
154
155// tracking
156#if defined(__CHUCK_STAT_TRACK__)
157#define CK_TRACK( stmt ) stmt
158#else
159#define CK_TRACK( stmt )
160#endif
161
162#ifdef __MACOSX_CORE__
163#define __PLATFORM_MACOSX__
164#endif
165
166#if defined(__LINUX_ALSA__) || defined(__LINUX_JACK__) || defined(__LINUX_OSS__) || defined(__LINUX_PULSE__) || defined(__UNIX_JACK__)
167// defined by default in Linux makefiles
168//#define __PLATFORM_LINUX__
169#endif
170
171#ifdef __PLATFORM_WIN32__
172#ifndef usleep
173#define usleep(x) Sleep( (x / 1000 <= 0 ? 1 : x / 1000) )
174#endif
175#pragma warning (disable : 4996) // stdio deprecation
176#pragma warning (disable : 4786) // stl debug info
177#pragma warning (disable : 4312) // type casts from void*
178#pragma warning (disable : 4311) // type casts to void*
179#pragma warning (disable : 4244) // truncation
180#pragma warning (disable : 4068) // unknown pragma
181#pragma warning (disable : 4018) // signed/unsigned mismatch
182#endif
183
184#ifdef __CHIP_MODE__
185#define __DISABLE_MIDI__
186//#define __DISABLE_SNDBUF__
187#define __DISABLE_WATCHDOG__
188#define __DISABLE_RAW__
189#define __DISABLE_KBHIT__
190#define __DISABLE_PROMPTER__
191#define __DISABLE_RTAUDIO__
192#define __DISABLE_OTF_SERVER__
193#define __ALTER_HID__
194#define __ALTER_ENTRY_POINT__
195#define __STK_USE_SINGLE_PRECISION__
196#endif
197
198#ifdef __arm__
199// enable additional optimization
200#define __STK_USE_SINGLE_PRECISION__
201#endif // __arm__
202
203#endif
core/chuck_dl.cpp+0−1151
@@ -1,1151 +0,0 @@
1/*----------------------------------------------------------------------------
2 ChucK Concurrent, On-the-fly Audio Programming Language
3 Compiler and Virtual Machine
4
5 Copyright (c) 2004 Ge Wang and Perry R. Cook. All rights reserved.
6 http://chuck.stanford.edu/
7 http://chuck.cs.princeton.edu/
8
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.
13
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.
18
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-----------------------------------------------------------------------------*/
24
25//-----------------------------------------------------------------------------
26// name: chuck_dl.cpp
27// desc: chuck dynamic linking header
28//
29// authors: Ge Wang (ge@ccrma.stanford.edu | gewang@cs.princeton.edu)
30// Ari Lazier (alazier@cs.princeton.edu)
31// Spencer Salazar (spencer@ccrma.stanford.edu)
32// mac os code based on apple's open source
33//
34// date: spring 2004 - 1.1
35// spring 2005 - 1.2
36//-----------------------------------------------------------------------------
37#include "chuck_dl.h"
38#include "chuck_errmsg.h"
39#include "chuck_type.h"
40#include "chuck_instr.h"
41#include "chuck_compile.h"
42#include "chuck_vm.h"
43#include <sstream>
44using namespace std;
45
46
47
48
49#if defined(__MACOSX_CORE__)
50char g_default_chugin_path[] = "/usr/local/lib/chuck:/Library/Application Support/ChucK/ChuGins:~/Library/Application Support/ChucK/ChuGins";
51#elif defined(__PLATFORM_WIN32__)
52char g_default_chugin_path[] = "C:\\WINDOWS\\system32\\ChucK;C:\\Program Files\\ChucK\\chugins;C:\\Program Files (x86)\\ChucK\\chugins";
53#else // Linux/Cygwin
54char g_default_chugin_path[] = "/usr/local/lib/chuck";
55#endif
56
57char g_chugin_path_envvar[] = "CHUCK_CHUGIN_PATH";
58
59
60
61
62//-----------------------------------------------------------------------------
63// internal implementation of query functions
64//-----------------------------------------------------------------------------
65
66
67
68t_CKUINT ck_builtin_declversion() { return CK_DLL_VERSION; }
69
70
71
72//-----------------------------------------------------------------------------
73// name: ck_setname()
74// desc: set the name of the module
75//-----------------------------------------------------------------------------
76void CK_DLL_CALL ck_setname( Chuck_DL_Query * query, const char * name )
77{
78 // set the name
79 query->dll_name = name;
80}
81
82
83
84
85//-----------------------------------------------------------------------------
86// name: ck_begin_class()
87// desc: begin class/namespace, can be nexted
88//-----------------------------------------------------------------------------
89void CK_DLL_CALL ck_begin_class( Chuck_DL_Query * query, const char * name, const char * parent )
90{
91 // find parent mvar offset
92 t_CKINT parent_offset = 0;
93 if(parent && parent[0] != '\0')
94 {
95 a_Id_List parent_path = str2list( parent );
96 if( !parent_path )
97 {
98 // error
99 EM_error2( 0, "class import: ck_begin_class: unknown parent type '%s'",
100 query->curr_class->name.c_str(), name, parent );
101 return;
102 }
103
104 Chuck_Type * ck_parent_type = type_engine_find_type( query->env(), parent_path );
105
106 delete_id_list( parent_path );
107
108 if( !ck_parent_type )
109 {
110 // error
111 EM_error2( 0, "class import: ck_begin_class: unable to find parent type '%s'", ck_parent_type );
112 return;
113 }
114
115 parent_offset = ck_parent_type->obj_size;
116 }
117
118 // push
119 query->stack.push_back( query->curr_class );
120 // allocate
121 Chuck_DL_Class * c = new Chuck_DL_Class;
122
123 // add class
124 if( query->curr_class )
125 // recursive
126 query->curr_class->classes.push_back( c );
127 // 1.3.2.0: do not save class for later import (will import it on class close)
128// else
129// // first level
130// query->classes.push_back( c );
131
132 // remember info
133 c->name = name;
134 c->parent = parent;
135 c->current_mvar_offset = parent_offset;
136
137 // curr
138 query->curr_class = c;
139 query->curr_func = NULL;
140}
141
142
143
144
145//-----------------------------------------------------------------------------
146// name: ck_add_ctor()
147// desc: add constructor, can be followed by add_arg
148//-----------------------------------------------------------------------------
149void CK_DLL_CALL ck_add_ctor( Chuck_DL_Query * query, f_ctor ctor )
150{
151 // make sure there is class
152 if( !query->curr_class )
153 {
154 // error
155 EM_error2( 0, "class import: add_ctor invoked without begin_class..." );
156 return;
157 }
158
159 // allocate
160 Chuck_DL_Func * f = new Chuck_DL_Func;
161 f->name = "[ctor]";
162 f->type = "void";
163 f->ctor = ctor;
164
165 // add
166 query->curr_class->ctors.push_back( f );
167 query->curr_func = f;
168}
169
170
171
172
173//-----------------------------------------------------------------------------
174// name: ck_add_dtor()
175// add destructor, no args allowed
176//-----------------------------------------------------------------------------
177void CK_DLL_CALL ck_add_dtor( Chuck_DL_Query * query, f_dtor dtor )
178{
179 // make sure there is class
180 if( !query->curr_class )
181 {
182 // error
183 EM_error2( 0, "class import: add_dtor invoked without begin_class..." );
184 return;
185 }
186
187 // make sure there are no duplicates
188 if( query->curr_class->dtor )
189 {
190 // error
191 EM_error2( 0, "class import: multiple dtor added ..." );
192 return;
193 }
194
195 // allocate
196 Chuck_DL_Func * f = new Chuck_DL_Func;
197 f->name = "[dtor]";
198 f->type = "void";
199 f->dtor = dtor;
200
201 // add
202 query->curr_class->dtor = f;
203 // set
204 query->curr_func = NULL;
205}
206
207
208
209
210//-----------------------------------------------------------------------------
211// name: ck_add_mfun()
212// desc: add member function, can be followed by add_arg
213//-----------------------------------------------------------------------------
214void CK_DLL_CALL ck_add_mfun( Chuck_DL_Query * query, f_mfun addr,
215 const char * type, const char * name )
216{
217 // make sure there is class
218 if( !query->curr_class )
219 {
220 // error
221 EM_error2( 0, "class import: add_mfun invoked without begin_class..." );
222 return;
223 }
224
225 // allocate
226 Chuck_DL_Func * f = new Chuck_DL_Func;
227 f->name = name;
228 f->type = type;
229 f->mfun = addr;
230
231 // add
232 query->curr_class->mfuns.push_back( f );
233 query->curr_func = f;
234}
235
236
237
238
239//-----------------------------------------------------------------------------
240// name: ck_add_sfun()
241// desc: add static function, can be followed by add_arg
242//-----------------------------------------------------------------------------
243void CK_DLL_CALL ck_add_sfun( Chuck_DL_Query * query, f_sfun addr,
244 const char * type, const char * name )
245{
246 // make sure there is class
247 if( !query->curr_class )
248 {
249 // error
250 EM_error2( 0, "class import: add_sfun invoked without begin_class..." );
251 return;
252 }
253
254 // allocate
255 Chuck_DL_Func * f = new Chuck_DL_Func;
256 f->name = name;
257 f->type = type;
258 f->sfun = addr;
259
260 // add
261 query->curr_class->sfuns.push_back( f );
262 query->curr_func = f;
263}
264
265
266
267
268//-----------------------------------------------------------------------------
269// name: ck_add_mvar()
270// desc: add member var
271//-----------------------------------------------------------------------------
272t_CKUINT CK_DLL_CALL ck_add_mvar( Chuck_DL_Query * query,
273 const char * type, const char * name,
274 t_CKBOOL is_const )
275{
276 // make sure there is class
277 if( !query->curr_class )
278 {
279 // error
280 EM_error2( 0, "class import: add_mvar invoked without begin_class..." );
281 return CK_INVALID_OFFSET;
282 }
283
284 a_Id_List path = str2list( type );
285 if( !path )
286 {
287 // error
288 EM_error2( 0, "class import: add_mvar: mvar %s.%s has unknown type '%s'",
289 query->curr_class->name.c_str(), name, type );
290 return CK_INVALID_OFFSET;
291 }
292
293 Chuck_Type * ck_type = type_engine_find_type( query->env(), path );
294
295 delete_id_list( path );
296
297 if( !ck_type )
298 {
299 // error
300 EM_error2( 0, "class import: add_mvar: unable to find type '%s'", type );
301 return CK_INVALID_OFFSET;
302 }
303
304 // allocate
305 Chuck_DL_Value * v = new Chuck_DL_Value;
306 v->name = name;
307 v->type = type;
308 v->is_const = is_const;
309
310 // add
311 query->curr_class->mvars.push_back( v );
312 query->curr_func = NULL;
313 query->last_var = v;
314
315 t_CKUINT offset = query->curr_class->current_mvar_offset;
316 query->curr_class->current_mvar_offset = type_engine_next_offset( query->curr_class->current_mvar_offset,
317 ck_type );
318
319 return offset;
320}
321
322
323
324
325//-----------------------------------------------------------------------------
326// name: ck_add_svar()
327// desc: add static var
328//-----------------------------------------------------------------------------
329void CK_DLL_CALL ck_add_svar( Chuck_DL_Query * query, const char * type, const char * name,
330 t_CKBOOL is_const, void * addr )
331{
332 // make sure there is class
333 if( !query->curr_class )
334 {
335 // error
336 EM_error2( 0, "class import: add_svar invoked without begin_class..." );
337 return;
338 }
339
340 // allocate
341 Chuck_DL_Value * v = new Chuck_DL_Value;
342 v->name = name;
343 v->type = type;
344 v->is_const = is_const;
345 v->static_addr = addr;
346
347 // add
348 query->curr_class->svars.push_back( v );
349 query->curr_func = NULL;
350
351 query->last_var = v;
352}
353
354
355
356
357//-----------------------------------------------------------------------------
358// name: ck_add_arg()
359// desc: add argument to function
360//-----------------------------------------------------------------------------
361void CK_DLL_CALL ck_add_arg( Chuck_DL_Query * query, const char * type, const char * name )
362{
363 // make sure there is class
364 if( !query->curr_class )
365 {
366 // error
367 EM_error2( 0, "class import: add_arg invoked without begin_class..." );
368 return;
369 }
370
371 // make sure there is function
372 if( !query->curr_func )
373 {
374 // error
375 EM_error2( 0, "class import: add_arg can only follow 'ctor', 'mfun', 'sfun', 'arg'..." );
376 return;
377 }
378
379 // allocate
380 Chuck_DL_Value * v = new Chuck_DL_Value;
381 v->name = name;
382 v->type = type;
383
384 // add
385 query->curr_func->args.push_back( v );
386}
387
388
389
390
391//-----------------------------------------------------------------------------
392// name: ck_add_ugen_func()
393// desc: (ugen only) add tick and pmsg functions
394//-----------------------------------------------------------------------------
395void CK_DLL_CALL ck_add_ugen_func( Chuck_DL_Query * query, f_tick ugen_tick, f_pmsg ugen_pmsg, t_CKUINT num_in, t_CKUINT num_out )
396{
397 // make sure there is class
398 if( !query->curr_class )
399 {
400 // error
401 EM_error2( 0, "class import: add_ugen_func invoked without begin_class..." );
402 return;
403 }
404
405 // make sure tick not defined already
406 if( query->curr_class->ugen_tick && ugen_tick )
407 {
408 // error
409 EM_error2( 0, "class import: ugen_tick already defined..." );
410 return;
411 }
412
413 // make sure pmsg not defined already
414 if( query->curr_class->ugen_pmsg && ugen_pmsg )
415 {
416 // error
417 EM_error2( 0, "class import: ugen_pmsg already defined..." );
418 return;
419 }
420
421 // set
422 if( ugen_tick ) query->curr_class->ugen_tick = ugen_tick;
423 if( ugen_pmsg ) query->curr_class->ugen_pmsg = ugen_pmsg;
424 query->curr_class->ugen_num_in = num_in;
425 query->curr_class->ugen_num_out = num_out;
426 query->curr_func = NULL;
427}
428
429
430
431
432//-----------------------------------------------------------------------------
433// name: ck_add_ugen_funcf()
434// desc: (ugen only) add tick and pmsg functions
435//-----------------------------------------------------------------------------
436void CK_DLL_CALL ck_add_ugen_funcf( Chuck_DL_Query * query, f_tickf ugen_tickf, f_pmsg ugen_pmsg, t_CKUINT num_in, t_CKUINT num_out )
437{
438 // make sure there is class
439 if( !query->curr_class )
440 {
441 // error
442 EM_error2( 0, "class import: add_ugen_func invoked without begin_class..." );
443 return;
444 }
445
446 // make sure tick not defined already
447 if( query->curr_class->ugen_tickf && ugen_tickf )
448 {
449 // error
450 EM_error2( 0, "class import: ugen_tick already defined..." );
451 return;
452 }
453
454 // make sure pmsg not defined already
455 if( query->curr_class->ugen_pmsg && ugen_pmsg )
456 {
457 // error
458 EM_error2( 0, "class import: ugen_pmsg already defined..." );
459 return;
460 }
461
462 // set
463 if( ugen_tickf ) query->curr_class->ugen_tickf = ugen_tickf;
464 if( ugen_pmsg ) query->curr_class->ugen_pmsg = ugen_pmsg;
465 query->curr_class->ugen_num_in = num_in;
466 query->curr_class->ugen_num_out = num_out;
467 query->curr_func = NULL;
468}
469
470
471
472
473//-----------------------------------------------------------------------------
474// name: ck_add_ugen_funcf_auto_num_channels()
475// desc: (ugen only) add tick and pmsg functions. specify num channels by vm.
476//-----------------------------------------------------------------------------
477void CK_DLL_CALL ck_add_ugen_funcf_auto_num_channels( Chuck_DL_Query * query,
478 f_tickf ugen_tickf, f_pmsg ugen_pmsg )
479{
480 ck_add_ugen_funcf( query, ugen_tickf, ugen_pmsg,
481 query->vm()->m_num_adc_channels,
482 query->vm()->m_num_dac_channels
483 );
484}
485
486
487
488
489//-----------------------------------------------------------------------------
490// name: ck_add_ugen_ctrl()
491// desc: (ugen only) add ctrl parameters
492//-----------------------------------------------------------------------------
493void CK_DLL_CALL ck_add_ugen_ctrl( Chuck_DL_Query * query, f_ctrl ugen_ctrl, f_cget ugen_cget,
494 const char * type, const char * name )
495{
496 // make sure there is class
497 if( !query->curr_class )
498 {
499 // error
500 EM_error2( 0, "class import: add_ugen_func invoked without begin_class..." );
501 return;
502 }
503
504 // allocate
505 Chuck_DL_Ctrl * c = new Chuck_DL_Ctrl;
506 c->name = name;
507 c->type = type;
508 c->ctrl = ugen_ctrl;
509 c->cget = ugen_cget;
510
511 // set
512 query->curr_func = NULL;
513}
514
515
516
517
518//-----------------------------------------------------------------------------
519// name: ck_end_class()
520// desc: end class/namespace, compile it
521//-----------------------------------------------------------------------------
522t_CKBOOL CK_DLL_CALL ck_end_class( Chuck_DL_Query * query )
523{
524 // make sure there is class
525 if( !query->curr_class )
526 {
527 // error
528 EM_error2( 0, "class import: end_class invoked without begin_class..." );
529 return FALSE;
530 }
531
532 // type check the class?
533 // 1.3.2.0: import class into type engine if at top level
534 if( query->stack.size() == 1 ) // top level class
535 {
536 if( !type_engine_add_class_from_dl( query->env(), query->curr_class ) )
537 {
538 EM_log(CK_LOG_SEVERE, "[chuck](DL): error importing class '%s' into type engine",
539 query->curr_class->name.c_str());
540
541 // pop
542 assert( query->stack.size() );
543 query->curr_class = query->stack.back();
544 query->stack.pop_back();
545
546 return FALSE;
547 }
548 }
549
550 // pop
551 assert( query->stack.size() );
552 query->curr_class = query->stack.back();
553 query->stack.pop_back();
554
555 return TRUE;
556}
557
558
559
560
561//-----------------------------------------------------------------------------
562// name: ck_doc_class()
563// desc: set current class documentation
564//-----------------------------------------------------------------------------
565t_CKBOOL CK_DLL_CALL ck_doc_class( Chuck_DL_Query * query, const char * doc )
566{
567#ifdef CK_DOC // disable unless CK_DOC
568 if(query->curr_class)
569 query->curr_class->doc = doc;
570 else
571 return FALSE;
572#endif // CK_DOC
573
574 return TRUE;
575}
576
577//-----------------------------------------------------------------------------
578// name: ck_add_example()
579// desc: set current class documentation
580//-----------------------------------------------------------------------------
581t_CKBOOL CK_DLL_CALL ck_add_example( Chuck_DL_Query * query, const char * ex )
582{
583#ifdef CK_DOC // disable unless CK_DOC
584 if(query->curr_class)
585 query->curr_class->examples.push_back(ex);
586 else
587 return FALSE;
588#endif // CK_DOC
589
590 return TRUE;
591}
592
593// set current function documentation
594t_CKBOOL CK_DLL_CALL ck_doc_func( Chuck_DL_Query * query, const char * doc )
595{
596#ifdef CK_DOC // disable unless CK_DOC
597 if(query->curr_func)
598 query->curr_func->doc = doc;
599 else
600 return FALSE;
601#endif // CK_DOC
602
603 return TRUE;
604}
605
606// set last mvar documentation
607t_CKBOOL CK_DLL_CALL ck_doc_var( Chuck_DL_Query * query, const char * doc )
608{
609#ifdef CK_DOC // disable unless CK_DOC
610 if(query->last_var)
611 query->last_var->doc = doc;
612 else
613 return FALSE;
614#endif // CK_DOC
615
616 return TRUE;
617}
618
619
620
621//------------------------------------------------------------------------------
622// alternative functions to make stuff
623//------------------------------------------------------------------------------
624Chuck_DL_Func * make_new_mfun( const char * t, const char * n, f_mfun mfun )
625{ return new Chuck_DL_Func( t, n, (t_CKUINT)mfun ); }
626Chuck_DL_Func * make_new_sfun( const char * t, const char * n, f_sfun sfun )
627{ return new Chuck_DL_Func( t, n, (t_CKUINT)sfun ); }
628Chuck_DL_Value * make_new_arg( const char * t, const char * n )
629{ return new Chuck_DL_Value( t, n ); }
630Chuck_DL_Value * make_new_mvar( const char * t, const char * n, t_CKBOOL c )
631{ return new Chuck_DL_Value( t, n, c ); }
632Chuck_DL_Value * make_new_svar( const char * t, const char * n, t_CKBOOL c, void * a )
633{ return new Chuck_DL_Value( t, n, c, a ); }
634
635
636
637
638//-----------------------------------------------------------------------------
639// name: load()
640// desc: load dynamic link library
641//-----------------------------------------------------------------------------
642t_CKBOOL Chuck_DLL::load( const char * filename, const char * func, t_CKBOOL lazy )
643{
644 // open
645 m_handle = dlopen( filename, lazy ? RTLD_LAZY : RTLD_NOW );
646
647 // still not there
648 if( !m_handle )
649 {
650 m_last_error = dlerror();
651 return FALSE;
652 }
653
654 // save the filename
655 m_filename = filename;
656 m_done_query = FALSE;
657 m_func = func;
658
659 // if not lazy, do it
660 if( !lazy && !this->query() )
661 return FALSE;
662
663 return TRUE;
664}
665
666
667
668
669//-----------------------------------------------------------------------------
670// name: load()
671// desc: load dynamic link library
672//-----------------------------------------------------------------------------
673t_CKBOOL Chuck_DLL::load( f_ck_query query_func, t_CKBOOL lazy )
674{
675 m_query_func = query_func;
676 m_version_func = ck_builtin_declversion;
677 m_done_query = FALSE;
678 m_func = "ck_query";
679
680 // if not lazy, do it
681 if( !lazy && !this->query() )
682 return FALSE;
683
684 return TRUE;
685}
686
687
688
689
690//-----------------------------------------------------------------------------
691// name: good()
692// desc: ...
693//-----------------------------------------------------------------------------
694t_CKBOOL Chuck_DLL::good() const
695{
696 return ( m_handle != NULL || m_query_func != NULL );
697}
698
699
700
701
702//-----------------------------------------------------------------------------
703// name: query()
704// desc: ...
705//-----------------------------------------------------------------------------
706const Chuck_DL_Query * Chuck_DLL::query( )
707{
708 if( !m_handle && !m_query_func )
709 {
710 m_last_error = "dynamic link library not loaded for query...";
711 return NULL;
712 }
713
714 // return if there already
715 if( m_done_query )
716 return &m_query;
717
718 // get the address of the DL version function from the DLL
719 if( !m_version_func )
720 m_version_func = (f_ck_declversion)this->get_addr( CK_DECLVERSION_FUNC );
721 if( !m_version_func )
722 m_version_func = (f_ck_declversion)this->get_addr( (string("_")+CK_DECLVERSION_FUNC).c_str() );
723 if( !m_version_func )
724 {
725 m_last_error = string("no version function found in dll '")
726 + m_filename + string("'");
727 return NULL;
728 }
729
730 // check version
731 t_CKUINT dll_version = m_version_func();
732 t_CKBOOL version_ok = FALSE;
733 // oops lets have version 4 be ok actually
734 if(CK_DLL_VERSION_GETMAJOR(dll_version) == 4)
735 version_ok = TRUE;
736 // major version must be same
737 // minor version must less than or equal
738 if(CK_DLL_VERSION_GETMAJOR(dll_version) == CK_DLL_VERSION_MAJOR &&
739 CK_DLL_VERSION_GETMINOR(dll_version) <= CK_DLL_VERSION_MINOR)
740 version_ok = TRUE;
741
742 if(!version_ok)
743 // SPENCERTODO: do they need to be equal, or can dll_version be < ?
744 {
745 ostringstream oss;
746 oss << "DL version not supported: "
747 << CK_DLL_VERSION_GETMAJOR(dll_version)
748 << "."
749 << CK_DLL_VERSION_GETMINOR(dll_version)
750 << " in '"
751 << m_filename
752 << "'";
753
754 m_last_error = oss.str();
755
756 return NULL;
757 }
758
759 // get the address of the query function from the DLL
760 if( !m_query_func )
761 m_query_func = (f_ck_query)this->get_addr( m_func.c_str() );
762 if( !m_query_func )
763 m_query_func = (f_ck_query)this->get_addr( (string("_")+m_func).c_str() );
764 if( !m_query_func )
765 {
766 m_last_error = string("no query function found in dll '")
767 + m_filename + string("'");
768 return NULL;
769 }
770
771 // get the address of the attach function from the DLL
772 /* if( !m_attach_func )
773 m_attach_func = (f_ck_attach)this->get_addr( "ck_attach" );
774 if( !m_attach_func )
775 m_attach_func = (f_ck_attach)this->get_addr( "_ck_attach" );
776
777 // get the address of the detach function from the DLL
778 if( !m_detach_func )
779 m_detach_func = (f_ck_detach)this->get_addr( "ck_detach" );
780 if( !m_detach_func )
781 m_detach_func = (f_ck_detach)this->get_addr( "_ck_detach" ); */
782
783 // do the query
784 m_query.clear();
785 if( !m_query_func( &m_query ) )
786 {
787 m_last_error = string("unsuccessful query in dll '") + m_filename
788 + string("'");
789 return NULL;
790 }
791
792 // load the proto table
793 /* Chuck_DL_Proto * proto;
794 m_name2proto.clear();
795 for( t_CKUINT i = 0; i < m_query.dll_exports.size(); i++ )
796 {
797 proto = &m_query.dll_exports[i];
798 if( m_name2proto[proto->name] )
799 {
800 m_last_error = string("duplicate export name '") + proto->name
801 + string("'");
802 return NULL;
803 }
804
805 // get the addr
806 if( !proto->addr )
807 proto->addr = (f_ck_func)this->get_addr( (char *)proto->name.c_str() );
808 if( !proto->addr )
809 {
810 m_last_error = string("no addr associated with export '") +
811 proto->name + string("'");
812 return NULL;
813 }
814
815 // put in the lookup table
816 m_name2proto[proto->name] = proto;
817 }
818
819 // load the proto table
820 Chuck_UGen_Info * info;
821 m_name2ugen.clear();
822 for( t_CKUINT j = 0; j < m_query.ugen_exports.size(); j++ )
823 {
824 info = &m_query.ugen_exports[j];
825 if( m_name2ugen[info->name] )
826 {
827 m_last_error = string("duplicate export ugen name '") + info->name
828 + string("'");
829 return NULL;
830 }
831
832 // put in the lookup table
833 m_name2ugen[info->name] = info;
834 }*/
835
836 m_done_query = TRUE;
837
838 // call attach
839 // if( m_attach_func ) m_attach_func( 0, NULL );
840
841 return &m_query;
842}
843
844
845
846
847//-----------------------------------------------------------------------------
848// name: unload()
849// desc: ...
850//-----------------------------------------------------------------------------
851t_CKBOOL Chuck_DLL::unload()
852{
853 if( !m_handle && !m_query_func )
854 {
855 m_last_error = "cannot unload dynamic library - nothing open...";
856 return FALSE;
857 }
858
859 // if( m_detach_func ) m_detach_func( 0, NULL );
860
861 if( m_handle )
862 {
863 dlclose( m_handle );
864 m_handle = NULL;
865 }
866 else
867 m_query_func = NULL;
868
869 return TRUE;
870}
871
872
873
874
875//-----------------------------------------------------------------------------
876// name: get_addr()
877// desc: ...
878//-----------------------------------------------------------------------------
879void * Chuck_DLL::get_addr( const char * symbol )
880{
881 if( !m_handle )
882 {
883 m_last_error = "cannot find addr from dynamic library - nothing open...";
884 return FALSE;
885 }
886
887 return dlsym( m_handle, symbol );
888}
889
890
891
892
893//-----------------------------------------------------------------------------
894// name: last_error()
895// desc: ...
896//-----------------------------------------------------------------------------
897const char * Chuck_DLL::last_error() const
898{
899 return m_last_error.c_str();
900}
901
902
903
904
905//-----------------------------------------------------------------------------
906// name: name()
907// desc: ...
908//-----------------------------------------------------------------------------
909const char * Chuck_DLL::name() const
910{
911 return m_id.c_str();
912}
913
914
915//const t_CKUINT Chuck_DL_Query::RESERVED_SIZE;
916
917//-----------------------------------------------------------------------------
918// name: Chuck_DL_Query
919// desc: ...
920//-----------------------------------------------------------------------------
921Chuck_DL_Query::Chuck_DL_Query( Chuck_Carrier * carrier )
922{
923 // set the pointers to functions so the module can call
924 setname = ck_setname;
925 begin_class = ck_begin_class;
926 add_ctor = ck_add_ctor;
927 add_dtor = ck_add_dtor;
928 add_mfun = ck_add_mfun;
929 add_sfun = ck_add_sfun;
930 add_mvar = ck_add_mvar;
931 add_svar = ck_add_svar;
932 add_arg = ck_add_arg;
933 add_ugen_func = ck_add_ugen_func;
934 add_ugen_funcf = ck_add_ugen_funcf;
935 add_ugen_funcf_auto_num_channels = ck_add_ugen_funcf_auto_num_channels;
936 add_ugen_ctrl = ck_add_ugen_ctrl;
937 end_class = ck_end_class;
938 doc_class = ck_doc_class;
939 doc_func = ck_doc_func;
940 doc_var = ck_doc_var;
941 m_carrier = carrier;
942
943// memset(reserved2, NULL, sizeof(void*)*RESERVED_SIZE);
944
945 dll_name = "[noname]";
946 reserved = NULL;
947 curr_class = NULL;
948 curr_func = NULL;
949
950 srate = carrier->vm->srate();
951
952 linepos = 0;
953}
954
955
956
957
958//-----------------------------------------------------------------------------
959// name: clear()
960// desc: ...
961//-----------------------------------------------------------------------------
962void Chuck_DL_Query::clear()
963{
964 // set to 0
965 dll_name = "[noname]";
966 // line pos
967 linepos = 0;
968 // delete classes
969 for( t_CKUINT i = 0; i < classes.size(); i++ ) delete classes[i];
970 // clear
971 classes.clear();
972}
973
974
975
976
977//-----------------------------------------------------------------------------
978// name: ~Chuck_DL_Class()
979// desc: ...
980//-----------------------------------------------------------------------------
981Chuck_DL_Class::~Chuck_DL_Class()
982{
983 t_CKUINT i;
984
985 // delete mfuns
986 for( i = 0; i < mfuns.size(); i++ ) delete mfuns[i];
987 // delete sfuns
988 for( i = 0; i < sfuns.size(); i++ ) delete sfuns[i];
989 // delete mvars
990 for( i = 0; i < mvars.size(); i++ ) delete mvars[i];
991 // delete svars
992 for( i = 0; i < svars.size(); i++ ) delete svars[i];
993 // delete classes
994 for( i = 0; i < classes.size(); i++ ) delete classes[i];
995}
996
997
998
999
1000//-----------------------------------------------------------------------------
1001// name: ~Chuck_DL_Func()
1002// desc: ...
1003//-----------------------------------------------------------------------------
1004Chuck_DL_Func::~Chuck_DL_Func()
1005{
1006 for( t_CKUINT i = 0; i < args.size(); i++ )
1007 delete args[i];
1008}
1009
1010
1011
1012
1013/*******************************************************************************
1014
1015 Chuck_DL_Api stuff
1016
1017*******************************************************************************/
1018
1019namespace Chuck_DL_Api
1020{
1021 Api Api::g_api;
1022}
1023
1024
1025static t_CKUINT ck_get_srate(CK_DL_API api, Chuck_VM_Shred * shred)
1026{
1027 return shred->vm_ref->srate();
1028}
1029
1030static Chuck_DL_Api::Type ck_get_type( CK_DL_API api, Chuck_VM_Shred * shred, std::string & name )
1031{
1032 Chuck_Env * env = shred->vm_ref->env();
1033 a_Id_List list = new_id_list( name.c_str(), 0 ); // TODO: nested types
1034
1035 Chuck_Type * t = type_engine_find_type( env, list );
1036
1037 delete_id_list( list );
1038
1039 return ( Chuck_DL_Api::Type ) t;
1040}
1041
1042static Chuck_DL_Api::Object ck_create( CK_DL_API api, Chuck_VM_Shred * shred, Chuck_DL_Api::Type t )
1043{
1044 assert( t != NULL );
1045
1046 Chuck_Type * type = ( Chuck_Type * ) t;
1047 Chuck_Object * o = instantiate_and_initialize_object( type, shred->vm_ref );
1048
1049 return ( Chuck_DL_Api::Object ) o;
1050}
1051
1052static Chuck_DL_Api::String ck_create_string( CK_DL_API api, Chuck_VM_Shred * shred, std::string & str )
1053{
1054 Chuck_String * string = ( Chuck_String * ) instantiate_and_initialize_object( shred->vm_ref->env()->t_string, shred->vm_ref );
1055
1056 string->set( str );
1057
1058 return ( Chuck_DL_Api::String ) string;
1059}
1060
1061static t_CKBOOL ck_get_mvar_int( CK_DL_API api, Chuck_DL_Api::Object, std::string &, t_CKINT & )
1062{
1063 return TRUE;
1064}
1065
1066static t_CKBOOL ck_get_mvar_float( CK_DL_API api, Chuck_DL_Api::Object, std::string &, t_CKFLOAT & )
1067{
1068 return TRUE;
1069}
1070
1071static t_CKBOOL ck_get_mvar_dur( CK_DL_API api, Chuck_DL_Api::Object, std::string &, t_CKDUR & )
1072{
1073 return TRUE;
1074}
1075
1076static t_CKBOOL ck_get_mvar_time( CK_DL_API api, Chuck_DL_Api::Object, std::string &, t_CKTIME & )
1077{
1078 return TRUE;
1079}
1080
1081static t_CKBOOL ck_get_mvar_string( CK_DL_API api, Chuck_DL_Api::Object, std::string &, Chuck_DL_Api::String & )
1082{
1083 return TRUE;
1084}
1085
1086static t_CKBOOL ck_get_mvar_object( CK_DL_API api, Chuck_DL_Api::Object, std::string &, Chuck_DL_Api::Object & )
1087{
1088 return TRUE;
1089}
1090
1091static t_CKBOOL ck_set_string( CK_DL_API api, Chuck_DL_Api::String s, std::string & str )
1092{
1093 assert( s != NULL );
1094
1095 Chuck_String * string = ( Chuck_String * ) s;
1096 string->set( str );
1097
1098 return TRUE;
1099}
1100
1101
1102Chuck_DL_Api::Api::VMApi::VMApi() :
1103get_srate(ck_get_srate)
1104{ }
1105
1106
1107Chuck_DL_Api::Api::ObjectApi::ObjectApi() :
1108get_type(ck_get_type),
1109create(ck_create),
1110create_string(ck_create_string),
1111get_mvar_int(ck_get_mvar_int),
1112get_mvar_float(ck_get_mvar_float),
1113get_mvar_dur(ck_get_mvar_dur),
1114get_mvar_time(ck_get_mvar_time),
1115get_mvar_string(ck_get_mvar_string),
1116get_mvar_object(ck_get_mvar_object),
1117set_string(ck_set_string)
1118{ }
1119
1120
1121// windows
1122#if defined(__WINDOWS_DS__)
1123extern "C"
1124{
1125#include <windows.h>
1126
1127void *dlopen( const char *path, int mode )
1128{
1129 return (void *)LoadLibrary(path);
1130}
1131
1132int dlclose( void *handle )
1133{
1134 FreeLibrary((HMODULE)handle);
1135 return 1;
1136}
1137
1138void *dlsym( void * handle, const char *symbol )
1139{
1140 return (void *)GetProcAddress((HMODULE)handle, symbol);
1141}
1142
1143const char * dlerror( void )
1144{
1145 int error = GetLastError();
1146 if( error == 0 ) return NULL;
1147 sprintf( dlerror_buffer, "%i", error );
1148 return dlerror_buffer;
1149}
1150}
1151#endif
core/chuck_dl.h+0−732
@@ -1,732 +0,0 @@
1/*----------------------------------------------------------------------------
2 ChucK Concurrent, On-the-fly Audio Programming Language
3 Compiler and Virtual Machine
4
5 Copyright (c) 2004 Ge Wang and Perry R. Cook. All rights reserved.
6 http://chuck.stanford.edu/
7 http://chuck.cs.princeton.edu/
8
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.
13
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.
18
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-----------------------------------------------------------------------------*/
24
25//-----------------------------------------------------------------------------
26// name: chuck_dl.h
27// desc: chuck dynamic linking header
28//
29// authors: Ge Wang (ge@ccrma.stanford.edu | gewang@cs.princeton.edu)
30// Ari Lazier (alazier@cs.princeton.edu)
31// Spencer Salazar (spencer@ccrma.stanford.edu)
32// mac os code based on apple's open source
33//
34// date: spring 2004 - 1.1
35// spring 2005 - 1.2
36//-----------------------------------------------------------------------------
37#ifndef __CHUCK_DL_H__
38#define __CHUCK_DL_H__
39
40#include "chuck_def.h"
41#include "chuck_oo.h"
42#include "chuck_carrier.h"
43#include <string>
44#include <vector>
45#include <map>
46
47
48// major version must be the same between chuck:chugin
49#define CK_DLL_VERSION_MAJOR (0x0006)
50// minor version of chugin must be less than or equal to chuck's
51#define CK_DLL_VERSION_MINOR (0x0000)
52#define CK_DLL_VERSION_MAKE(maj,min) ((t_CKUINT)(((maj) << 16) | (min)))
53#define CK_DLL_VERSION_GETMAJOR(v) (((v) >> 16) & 0xFFFF)
54#define CK_DLL_VERSION_GETMINOR(v) ((v) & 0xFFFF)
55#define CK_DLL_VERSION (CK_DLL_VERSION_MAKE(CK_DLL_VERSION_MAJOR, CK_DLL_VERSION_MINOR))
56
57
58
59
60extern char g_default_chugin_path[];
61extern char g_chugin_path_envvar[];
62
63
64
65// forward references
66struct Chuck_DL_Query;
67struct Chuck_DL_Class;
68struct Chuck_DL_Func;
69struct Chuck_DL_Value;
70struct Chuck_DL_Ctrl;
71union Chuck_DL_Return;
72struct Chuck_DLL;
73struct Chuck_UGen;
74struct Chuck_UAna;
75struct Chuck_UAnaBlobProxy;
76namespace Chuck_DL_Api { struct Api; }
77
78
79// param conversion - to extract values from ARGS to functions
80#define GET_CK_FLOAT(ptr) (*(t_CKFLOAT *)ptr)
81#define GET_CK_SINGLE(ptr) (*(float *)ptr)
82#define GET_CK_DOUBLE(ptr) (*(double *)ptr)
83#define GET_CK_INT(ptr) (*(t_CKINT *)ptr)
84#define GET_CK_UINT(ptr) (*(t_CKUINT *)ptr)
85#define GET_CK_TIME(ptr) (*(t_CKTIME *)ptr)
86#define GET_CK_DUR(ptr) (*(t_CKDUR *)ptr)
87#define GET_CK_COMPLEX(ptr) (*(t_CKCOMPLEX *)ptr)
88#define GET_CK_POLAR(ptr) (*(t_CKPOLAR *)ptr)
89#define GET_CK_VEC3(ptr) (*(t_CKVEC3 *)ptr)
90#define GET_CK_VEC4(ptr) (*(t_CKVEC4 *)ptr)
91#define GET_CK_VECTOR(ptr) (*(t_CKVECTOR *)ptr)
92#define GET_CK_OBJECT(ptr) (*(Chuck_Object **)ptr)
93#define GET_CK_STRING(ptr) (*(Chuck_String **)ptr)
94
95// param conversion with pointer advance
96#define GET_NEXT_FLOAT(ptr) (*((t_CKFLOAT *&)ptr)++)
97#define GET_NEXT_SINGLE(ptr) (*((float *&)ptr)++)
98#define GET_NEXT_DOUBLE(ptr) (*((double *&)ptr)++)
99#define GET_NEXT_INT(ptr) (*((t_CKINT *&)ptr)++)
100#define GET_NEXT_UINT(ptr) (*((t_CKUINT *&)ptr)++)
101#define GET_NEXT_TIME(ptr) (*((t_CKTIME *&)ptr)++)
102#define GET_NEXT_DUR(ptr) (*((t_CKDUR *&)ptr)++)
103#define GET_NEXT_COMPLEX(ptr) (*((t_CKCOMPLEX *&)ptr)++)
104#define GET_NEXT_POLAR(ptr) (*((t_CKPOLAR *&)ptr)++)
105#define GET_NEXT_VEC3(ptr) (*((t_CKVEC3 *&)ptr)++)
106#define GET_NEXT_VEC4(ptr) (*((t_CKVEC4 *&)ptr)++)
107#define GET_NEXT_VECTOR(ptr) (*((t_CKVECTOR *&)ptr)++)
108#define GET_NEXT_OBJECT(ptr) (*((Chuck_Object **&)ptr)++)
109#define GET_NEXT_STRING(ptr) (*((Chuck_String **&)ptr)++)
110
111// param conversion
112#define SET_CK_FLOAT(ptr,v) (*(t_CKFLOAT *&)ptr=v)
113#define SET_CK_SINGLE(ptr,v) (*(float *&)ptr=v)
114#define SET_CK_DOUBLE(ptr,v) (*(double *&)ptr=v)
115#define SET_CK_INT(ptr,v) (*(t_CKINT *&)ptr=v)
116#define SET_CK_UINT(ptr,v) (*(t_CKUINT *&)ptr=v)
117#define SET_CK_TIME(ptr,v) (*(t_CKTIME *&)ptr=v)
118#define SET_CK_DUR(ptr,v) (*(t_CKDUR *&)ptr=v)
119#define SET_CK_VEC3(ptr,v) (*(t_CKVEC3 *&)ptr=v)
120#define SET_CK_VEC4(ptr,v) (*(t_CKVEC4 *&)ptr=v)
121#define SET_CK_VECTOR(ptr,v) (*(t_CKVECTOR *&)ptr=v)
122#define SET_CK_STRING(ptr,v) (*(Chuck_String **&)ptr=v)
123
124// param conversion with pointer advance
125#define SET_NEXT_FLOAT(ptr,v) (*((t_CKFLOAT *&)ptr)++=v)
126#define SET_NEXT_SINGLE(ptr,v) (*((float *&)ptr)++=v)
127#define SET_NEXT_DOUBLE(ptr,v) (*((double *&)ptr)++=v)
128#define SET_NEXT_INT(ptr,v) (*((t_CKINT *&)ptr)++=v)
129#define SET_NEXT_UINT(ptr,v) (*((t_CKUINT *&)ptr)++=v)
130#define SET_NEXT_TIME(ptr,v) (*((t_CKTIME *&)ptr)++=v)
131#define SET_NEXT_DUR(ptr,v) (*((t_CKDUR *&)ptr)++=v)
132#define SET_NEXT_VEC3(ptr,v) (*((t_CKVEC3 *&)ptr)++=v)
133#define SET_NEXT_VEC4(ptr,v) (*((t_CKVEC4 *&)ptr)++=v)
134#define SET_NEXT_VECTOR(ptr,v) (*((t_CKVECTOR *&)ptr)++=v)
135#define SET_NEXT_STRING(ptr,v) (*((Chuck_String **&)ptr)++=v)
136
137// param conversion - to extract values from object's data segment
138#define OBJ_MEMBER_DATA(obj,offset) (obj->data + offset)
139#define OBJ_MEMBER_FLOAT(obj,offset) (*(t_CKFLOAT *)OBJ_MEMBER_DATA(obj,offset))
140#define OBJ_MEMBER_SINGLE(obj,offset) (*(float *)OBJ_MEMBER_DATA(obj,offset))
141#define OBJ_MEMBER_DOUBLE(obj,offset) (*(double *)OBJ_MEMBER_DATA(obj,offset))
142#define OBJ_MEMBER_INT(obj,offset) (*(t_CKINT *)OBJ_MEMBER_DATA(obj,offset))
143#define OBJ_MEMBER_UINT(obj,offset) (*(t_CKUINT *)OBJ_MEMBER_DATA(obj,offset))
144#define OBJ_MEMBER_TIME(obj,offset) (*(t_CKTIME *)OBJ_MEMBER_DATA(obj,offset))
145#define OBJ_MEMBER_DUR(obj,offset) (*(t_CKDUR *)OBJ_MEMBER_DATA(obj,offset))
146#define OBJ_MEMBER_VEC3(obj,offset) (*(t_CKVEC3 *)OBJ_MEMBER_DATA(obj,offset))
147#define OBJ_MEMBER_VEC4(obj,offset) (*(t_CKVEC4 *)OBJ_MEMBER_DATA(obj,offset))
148#define OBJ_MEMBER_VECTOR(obj,offset) (*(t_CKVECTOR *)OBJ_MEMBER_DATA(obj,offset))
149#define OBJ_MEMBER_OBJECT(obj,offset) (*(Chuck_Object **)OBJ_MEMBER_DATA(obj,offset))
150#define OBJ_MEMBER_STRING(obj,offset) (*(Chuck_String **)OBJ_MEMBER_DATA(obj,offset))
151
152
153// chuck dll export linkage and calling convention
154#if defined (__PLATFORM_WIN32__)
155 #define CK_DLL_LINKAGE extern "C" __declspec( dllexport )
156#else
157 #define CK_DLL_LINKAGE extern "C"
158#endif
159
160// calling convention of functions provided by chuck to the dll
161#if defined(__WINDOWS_DS__)
162 #define CK_DLL_CALL _cdecl
163#else
164 #define CK_DLL_CALL
165#endif
166
167typedef const Chuck_DL_Api::Api *CK_DL_API;
168
169// macro for defining ChucK DLL export functions
170// example: CK_DLL_EXPORT(int) foo() { return 1; }
171#define CK_DLL_EXPORT(type) CK_DLL_LINKAGE type CK_DLL_CALL
172// macro for declaring version of ChucK DL a given DLL links to
173// example: CK_DLL_DECLVERSION
174#define CK_DLL_DECLVERSION CK_DLL_EXPORT(t_CKUINT) ck_version() { return CK_DLL_VERSION; }
175// naming convention for static query functions
176#define CK_DLL_QUERY_STATIC_NAME(name) ck_##name##_query
177// macro for defining ChucK DLL export query-functions (static version)
178#define CK_DLL_QUERY_STATIC(name) CK_DLL_EXPORT(t_CKBOOL) CK_DLL_QUERY_STATIC_NAME(name)( Chuck_DL_Query * QUERY )
179// macro for defining ChucK DLL export query-functions
180// example: CK_DLL_QUERY
181#ifndef __CK_DLL_STATIC__
182#define CK_DLL_QUERY(name) CK_DLL_DECLVERSION CK_DLL_EXPORT(t_CKBOOL) ck_query( Chuck_DL_Query * QUERY )
183#else
184#define CK_DLL_QUERY(name) CK_DLL_QUERY_STATIC(name)
185#endif // __CK_DLL_STATIC__
186// macro for defining ChucK DLL export allocator
187// example: CK_DLL_ALLOC(foo)
188#define CK_DLL_ALLOC(name) CK_DLL_EXPORT(Chuck_Object *) name( Chuck_VM_Shred * SHRED, CK_DL_API API )
189// macro for defining ChucK DLL export constructors
190// example: CK_DLL_CTOR(foo)
191#define CK_DLL_CTOR(name) CK_DLL_EXPORT(void) name( Chuck_Object * SELF, void * ARGS, Chuck_VM_Shred * SHRED, CK_DL_API API )
192// macro for defining ChucK DLL export destructors
193// example: CK_DLL_DTOR(foo)
194#define CK_DLL_DTOR(name) CK_DLL_EXPORT(void) name( Chuck_Object * SELF, Chuck_VM_Shred * SHRED, CK_DL_API API )
195// macro for defining ChucK DLL export member functions
196// example: CK_DLL_MFUN(foo)
197#define CK_DLL_MFUN(name) CK_DLL_EXPORT(void) name( Chuck_Object * SELF, void * ARGS, Chuck_DL_Return * RETURN, Chuck_VM_Shred * SHRED, CK_DL_API API )
198// macro for defining ChucK DLL export static functions
199// example: CK_DLL_SFUN(foo)
200#define CK_DLL_SFUN(name) CK_DLL_EXPORT(void) name( void * ARGS, Chuck_DL_Return * RETURN, Chuck_VM_Shred * SHRED, CK_DL_API API )
201// macro for defining ChucK DLL export ugen tick functions
202// example: CK_DLL_TICK(foo)
203#define CK_DLL_TICK(name) CK_DLL_EXPORT(t_CKBOOL) name( Chuck_Object * SELF, SAMPLE in, SAMPLE * out, Chuck_VM_Shred * SHRED, CK_DL_API API )
204// macro for defining ChucK DLL export ugen multi-channel tick functions
205// example: CK_DLL_TICKF(foo)
206#define CK_DLL_TICKF(name) CK_DLL_EXPORT(t_CKBOOL) name( Chuck_Object * SELF, SAMPLE * in, SAMPLE * out, t_CKUINT nframes, Chuck_VM_Shred * SHRED, CK_DL_API API )
207// macro for defining ChucK DLL export ugen ctrl functions
208// example: CK_DLL_CTRL(foo)
209#define CK_DLL_CTRL(name) CK_DLL_EXPORT(void) name( Chuck_Object * SELF, void * ARGS, Chuck_DL_Return * RETURN, Chuck_VM_Shred * SHRED, CK_DL_API API )
210// macro for defining ChucK DLL export ugen cget functions
211// example: CK_DLL_CGET(foo)
212#define CK_DLL_CGET(name) CK_DLL_EXPORT(void) name( Chuck_Object * SELF, void * ARGS, Chuck_DL_Return * RETURN, Chuck_VM_Shred * SHRED, CK_DL_API API )
213// macro for defining ChucK DLL export ugen pmsg functions
214// example: CK_DLL_PMSG(foo)
215#define CK_DLL_PMSG(name) CK_DLL_EXPORT(t_CKBOOL) name( Chuck_Object * SELF, const char * MSG, void * ARGS, Chuck_VM_Shred * SHRED, CK_DL_API API )
216// macro for defining ChucK DLL export uana tock functions
217// example: CK_DLL_TOCK(foo)
218#define CK_DLL_TOCK(name) CK_DLL_EXPORT(t_CKBOOL) name( Chuck_Object * SELF, Chuck_UAna * UANA, Chuck_UAnaBlobProxy * BLOB, Chuck_VM_Shred * SHRED, CK_DL_API API )
219
220
221// macros for DLL exports
222// example: DLL_QUERY query( Chuck_DL_Query * QUERY )
223// example: DLL_FUNC foo( void * ARGS, Chuck_DL_Return * RETURN )
224// example: DLL_UGEN_F foo_tick( Chuck_UGen * SELF, SAMPLE, SAMPLE * out );
225#define DLL_QUERY CK_DLL_EXPORT(t_CKBOOL)
226#define DLL_FUNC CK_DLL_EXPORT(void)
227#define UGEN_CTOR CK_DLL_EXPORT(void *)
228#define UGEN_DTOR CK_DLL_EXPORT(void)
229#define UGEN_TICK CK_DLL_EXPORT(t_CKBOOL)
230#define UGEN_PMSG CK_DLL_EXPORT(t_CKBOOL)
231#define UGEN_CTRL CK_DLL_EXPORT(t_CKVOID)
232#define UGEN_CGET CK_DLL_EXPORT(t_CKVOID)
233#define UANA_TOCK CK_DLL_EXPORT(t_CKBOOL)
234
235
236//-----------------------------------------------------------------------------
237// dynamic linking class interface prototypes
238//-----------------------------------------------------------------------------
239extern "C" {
240// query
241typedef t_CKUINT (CK_DLL_CALL * f_ck_declversion)();
242typedef t_CKBOOL (CK_DLL_CALL * f_ck_query)( Chuck_DL_Query * QUERY );
243// object
244typedef Chuck_Object * (CK_DLL_CALL * f_alloc)( Chuck_VM_Shred * SHRED, CK_DL_API API );
245typedef t_CKVOID (CK_DLL_CALL * f_ctor)( Chuck_Object * SELF, void * ARGS, Chuck_VM_Shred * SHRED, CK_DL_API API );
246typedef t_CKVOID (CK_DLL_CALL * f_dtor)( Chuck_Object * SELF, Chuck_VM_Shred * SHRED, CK_DL_API API );
247typedef t_CKVOID (CK_DLL_CALL * f_mfun)( Chuck_Object * SELF, void * ARGS, Chuck_DL_Return * RETURN, Chuck_VM_Shred * SHRED, CK_DL_API API );
248typedef t_CKVOID (CK_DLL_CALL * f_sfun)( void * ARGS, Chuck_DL_Return * RETURN, Chuck_VM_Shred * SHRED, CK_DL_API API );
249// ugen specific
250typedef t_CKBOOL (CK_DLL_CALL * f_tick)( Chuck_Object * SELF, SAMPLE in, SAMPLE * out, Chuck_VM_Shred * SHRED, CK_DL_API API );
251typedef t_CKBOOL (CK_DLL_CALL * f_tickf)( Chuck_Object * SELF, SAMPLE * in, SAMPLE * out, t_CKUINT nframes, Chuck_VM_Shred * SHRED, CK_DL_API API );
252typedef t_CKVOID (CK_DLL_CALL * f_ctrl)( Chuck_Object * SELF, void * ARGS, Chuck_DL_Return * RETURN, Chuck_VM_Shred * SHRED, CK_DL_API API );
253typedef t_CKVOID (CK_DLL_CALL * f_cget)( Chuck_Object * SELF, void * ARGS, Chuck_DL_Return * RETURN, Chuck_VM_Shred * SHRED, CK_DL_API API );
254typedef t_CKBOOL (CK_DLL_CALL * f_pmsg)( Chuck_Object * SELF, const char * MSG, void * ARGS, Chuck_VM_Shred * SHRED, CK_DL_API API );
255// uana specific
256typedef t_CKBOOL (CK_DLL_CALL * f_tock)( Chuck_Object * SELF, Chuck_UAna * UANA, Chuck_UAnaBlobProxy * BLOB, Chuck_VM_Shred * SHRED, CK_DL_API API );
257// "main thread" hook
258typedef t_CKBOOL (CK_DLL_CALL * f_mainthreadhook)( void * bindle );
259// "main thread" quit (stop running hook)
260typedef t_CKBOOL (CK_DLL_CALL * f_mainthreadquit)( void * bindle );
261}
262
263
264// default name in DLL/ckx to look for
265#define CK_QUERY_FUNC "ck_query"
266// default name in DLL/ckx to look for
267#define CK_DECLVERSION_FUNC "ck_version"
268// bad object data offset
269#define CK_INVALID_OFFSET 0xffffffff
270
271
272//-----------------------------------------------------------------------------
273// chuck DLL query functions, implemented on chuck side for portability
274//-----------------------------------------------------------------------------
275extern "C" {
276// set name of ckx
277typedef void ( CK_DLL_CALL * f_setname)( Chuck_DL_Query * query, const char * name );
278
279// begin class/namespace, can be nested
280typedef void (CK_DLL_CALL * f_begin_class)( Chuck_DL_Query * query, const char * name, const char * parent );
281// add constructor, must be betwen begin/end_class : use f_add_arg to add arguments immediately after
282typedef void (CK_DLL_CALL * f_add_ctor)( Chuck_DL_Query * query, f_ctor ctor );
283// add destructor - cannot have args
284typedef void (CK_DLL_CALL * f_add_dtor)( Chuck_DL_Query * query, f_dtor dtor );
285// add member function - args to follow
286typedef void (CK_DLL_CALL * f_add_mfun)( Chuck_DL_Query * query, f_mfun mfun, const char * type, const char * name );
287// add static function - args to follow
288typedef void (CK_DLL_CALL * f_add_sfun)( Chuck_DL_Query * query, f_sfun sfun, const char * type, const char * name );
289// add member variable
290typedef t_CKUINT (CK_DLL_CALL * f_add_mvar)( Chuck_DL_Query * query,
291 const char * type, const char * name, t_CKBOOL is_const ); // TODO: public/protected/private
292// add static variable
293typedef void (CK_DLL_CALL * f_add_svar)( Chuck_DL_Query * query,
294 const char * type, const char * name,
295 t_CKBOOL is_const, void * static_addr ); // TODO: public/protected/private
296// add arg - follows ctor mfun sfun
297typedef void (CK_DLL_CALL * f_add_arg)( Chuck_DL_Query * query, const char * type, const char * name );
298// ** functions for adding unit generators, must extend ugen
299typedef void (CK_DLL_CALL * f_add_ugen_func)( Chuck_DL_Query * query, f_tick tick, f_pmsg pmsg, t_CKUINT num_in, t_CKUINT num_out );
300typedef void (CK_DLL_CALL * f_add_ugen_funcf)( Chuck_DL_Query * query, f_tickf tickf, f_pmsg pmsg, t_CKUINT num_in, t_CKUINT num_out );
301typedef void (CK_DLL_CALL * f_add_ugen_funcf_auto_num_channels)( Chuck_DL_Query * query, f_tickf tickf, f_pmsg psmg );
302// ** add a ugen control
303typedef void (CK_DLL_CALL * f_add_ugen_ctrl)( Chuck_DL_Query * query, f_ctrl ctrl, f_cget cget,
304 const char * type, const char * name );
305// end class/namespace - must correspondent with begin_class. returns false on error
306typedef t_CKBOOL (CK_DLL_CALL * f_end_class)( Chuck_DL_Query * query );
307
308// documentation
309// set current class documentation
310typedef t_CKBOOL (CK_DLL_CALL * f_doc_class)( Chuck_DL_Query * query, const char * doc );
311// add example of current class
312typedef t_CKBOOL (CK_DLL_CALL * f_add_example)( Chuck_DL_Query * query, const char * ex );
313// set current function documentation
314typedef t_CKBOOL (CK_DLL_CALL * f_doc_func)( Chuck_DL_Query * query, const char * doc );
315// set last mvar documentation
316typedef t_CKBOOL (CK_DLL_CALL * f_doc_var)( Chuck_DL_Query * query, const char * doc );
317}
318
319
320//-----------------------------------------------------------------------------
321// name: struct Chuck_DL_Query
322// desc: passed to module
323//-----------------------------------------------------------------------------
324struct Chuck_DL_Query
325{
326protected:
327 // REFACTOR-2017: carrier ref
328 Chuck_Carrier * m_carrier;
329
330public:
331 // REFACTOR-2017: get associated compiler, vm, env
332 Chuck_Compiler * compiler() const { return m_carrier->compiler; }
333 Chuck_VM * vm() const { return m_carrier->vm; }
334 Chuck_Env * env() const { return m_carrier->env; }
335
336public:
337 // function pointers - to be called from client module
338 // QUERY->setname( QUERY, ... );
339 //
340 // set the name of the module
341 f_setname setname;
342 // begin class/namespace, can be nexted
343 f_begin_class begin_class;
344 // add constructor, can be followed by add_arg
345 f_add_ctor add_ctor;
346 // add destructor, no args allowed
347 f_add_dtor add_dtor;
348 // add member function, can be followed by add_arg
349 f_add_mfun add_mfun;
350 // add static function, can be followed by add_arg
351 f_add_sfun add_sfun;
352 // add member variable
353 f_add_mvar add_mvar;
354 // add static variable
355 f_add_svar add_svar;
356 // add argument to function
357 f_add_arg add_arg;
358 // (ugen only) add tick and pmsg functions
359 f_add_ugen_func add_ugen_func;
360 // (ugen only) add tick and pmsg functions
361 f_add_ugen_funcf add_ugen_funcf;
362 // (ugen only) add tick and pmsg functions, specify channels by vm
363 f_add_ugen_funcf_auto_num_channels add_ugen_funcf_auto_num_channels;
364 // (ugen only) add ctrl parameters
365 f_add_ugen_ctrl add_ugen_ctrl;
366 // end class/namespace, compile it
367 f_end_class end_class;
368
369 // added 1.3.5
370 Chuck_DL_Value * last_var;
371 f_doc_class doc_class;
372 f_doc_func doc_func;
373 f_doc_var doc_var;
374 f_add_example add_ex;
375
376 // NOTE: everything below std::anything cannot be reliably accessed
377 // by offset between dynamic modules, since std::anything could be variable
378 // size -- put everything need to be accessed across modules above here!
379 // discovered by the vigilant and forever traumatized Jack Atherton,
380 // fixed during REFACTOR-2017; warning by the guilt-ridden Ge Wang
381
382 // dll
383 Chuck_DLL * dll_ref;
384 // reserved
385 void * reserved;
386 // sample rate
387 t_CKUINT srate;
388 // line pos
389 int linepos;
390 // name of dll
391 std::string dll_name;
392
393 // current class
394 Chuck_DL_Class * curr_class;
395 // current function
396 Chuck_DL_Func * curr_func;
397 // name
398 std::string name;
399 // collection of class
400 std::vector<Chuck_DL_Class *> classes;
401 // stack
402 std::vector<Chuck_DL_Class * >stack;
403
404 // constructor
405 Chuck_DL_Query( Chuck_Carrier * carrier );
406 // desctructor
407 ~Chuck_DL_Query() { this->clear(); }
408 // clear
409 void clear();
410};
411
412
413
414
415//-----------------------------------------------------------------------------
416// name: struct Chuck_DL_Class
417// desc: class built from module
418//-----------------------------------------------------------------------------
419struct Chuck_DL_Class
420{
421 // the name of the class
422 std::string name;
423 // the name of the parent
424 std::string parent;
425 // ctor
426 std::vector<Chuck_DL_Func *> ctors;
427 // dtor
428 Chuck_DL_Func * dtor;
429 // mfun
430 std::vector<Chuck_DL_Func *> mfuns;
431 // sfun
432 std::vector<Chuck_DL_Func *> sfuns;
433 // mdata
434 std::vector<Chuck_DL_Value *> mvars;
435 // sdata
436 std::vector<Chuck_DL_Value *> svars;
437 // ugen_tick
438 f_tick ugen_tick;
439 // ugen_tickf
440 f_tickf ugen_tickf;
441 // ugen_pmsg
442 f_pmsg ugen_pmsg;
443 // ugen_ctrl/cget
444 std::vector<Chuck_DL_Ctrl *> ugen_ctrl;
445 // uana_tock
446 f_tock uana_tock;
447 // collection of recursive classes
448 std::vector<Chuck_DL_Class *> classes;
449 // current mvar offset
450 t_CKUINT current_mvar_offset;
451
452 t_CKUINT ugen_num_in, ugen_num_out;
453
454 std::string doc;
455 std::vector<std::string> examples;
456
457 // constructor
458 Chuck_DL_Class() { dtor = NULL; ugen_tick = NULL; ugen_tickf = NULL; ugen_pmsg = NULL; uana_tock = NULL; ugen_pmsg = NULL; current_mvar_offset = 0; ugen_num_in = ugen_num_out = 0; }
459 // destructor
460 ~Chuck_DL_Class();
461};
462
463
464
465
466//-----------------------------------------------------------------------------
467// name: struct Chuck_DL_Value
468// desc: value from module
469//-----------------------------------------------------------------------------
470struct Chuck_DL_Value
471{
472 // the name of the value
473 std::string name;
474 // the type of the value
475 std::string type;
476 // is const
477 t_CKBOOL is_const;
478 // addr static
479 void * static_addr;
480 // description
481 std::string doc;
482
483 // constructor
484 Chuck_DL_Value() { is_const = FALSE; static_addr = NULL; }
485 Chuck_DL_Value( const char * t, const char * n, t_CKBOOL c = FALSE, void * a = NULL )
486 { name = n; type = t; is_const = c; static_addr = a; }
487};
488
489
490
491
492//-----------------------------------------------------------------------------
493// name: struct Chuck_DL_Func
494// desc: function from module
495//-----------------------------------------------------------------------------
496struct Chuck_DL_Func
497{
498 // the name of the function
499 std::string name;
500 // the return type
501 std::string type;
502 // the pointer
503 union { f_ctor ctor; f_dtor dtor; f_mfun mfun; f_sfun sfun; t_CKUINT addr; };
504 // arguments
505 std::vector<Chuck_DL_Value *> args;
506 // description
507 std::string doc;
508
509 // constructor
510 Chuck_DL_Func() { ctor = NULL; }
511 Chuck_DL_Func( const char * t, const char * n, t_CKUINT a )
512 { name = n; type = t; addr = a; }
513 // destructor
514 ~Chuck_DL_Func();
515 // add arg
516 void add_arg( const char * t, const char * n )
517 { args.push_back( new Chuck_DL_Value( t, n ) ); }
518};
519
520
521
522
523//-----------------------------------------------------------------------------
524// name: struct Chuck_DL_Ctrl
525// desc: ctrl for ugen
526//-----------------------------------------------------------------------------
527struct Chuck_DL_Ctrl
528{
529 // the name of the ctrl
530 std::string name;
531 // the first type
532 std::string type;
533 // the types of the value
534 std::vector<std::string> types;
535 // ctrl
536 f_ctrl ctrl;
537 // cget
538 f_cget cget;
539};
540
541
542
543
544//------------------------------------------------------------------------------
545// alternative functions to make stuff
546//------------------------------------------------------------------------------
547Chuck_DL_Func * make_new_mfun( const char * t, const char * n, f_mfun mfun );
548Chuck_DL_Func * make_new_sfun( const char * t, const char * n, f_sfun sfun );
549Chuck_DL_Value * make_new_arg( const char * t, const char * n );
550Chuck_DL_Value * make_new_mvar( const char * t, const char * n, t_CKBOOL c = FALSE );
551Chuck_DL_Value * make_new_svar( const char * t, const char * n, t_CKBOOL c, void * a );
552
553
554
555
556//------------------------------------------------------------------------------
557// name: union Chuck_DL_Return
558// desc: dynamic link return function return struct
559//------------------------------------------------------------------------------
560union Chuck_DL_Return
561{
562 t_CKINT v_int;
563 t_CKUINT v_uint;
564 t_CKFLOAT v_float;
565 t_CKDUR v_dur;
566 t_CKTIME v_time;
567 t_CKCOMPLEX v_complex;
568 t_CKPOLAR v_polar;
569 t_CKVEC3 v_vec3; // ge: added 1.3.5.3
570 t_CKVEC4 v_vec4; // ge: added 1.3.5.3
571 Chuck_Object * v_object;
572 Chuck_String * v_string;
573
574 Chuck_DL_Return() { v_vec4.x = v_vec4.y = v_vec4.z = v_vec4.w = 0; }
575};
576
577
578
579
580//-----------------------------------------------------------------------------
581// name: struct Chuck_DLL
582// desc: dynamic link library
583//-----------------------------------------------------------------------------
584struct Chuck_DLL : public Chuck_VM_Object
585{
586public:
587 // load dynamic ckx/dll from filename
588 t_CKBOOL load( const char * filename,
589 const char * func = CK_QUERY_FUNC,
590 t_CKBOOL lazy = FALSE );
591 t_CKBOOL load( f_ck_query query_func, t_CKBOOL lazy = FALSE );
592 // get address in loaded ckx
593 void * get_addr( const char * symbol );
594 // get last error
595 const char * last_error() const;
596 // unload the ckx
597 t_CKBOOL unload( );
598 // query the content of the dll
599 const Chuck_DL_Query * query( );
600 // is good
601 t_CKBOOL good() const;
602 // name
603 const char * name() const;
604
605public:
606 // constructor
607 Chuck_DLL( Chuck_Carrier * carrier, const char * xid = NULL )
608 : m_handle(NULL), m_id(xid ? xid : ""),
609 m_query( carrier ),
610 m_done_query(FALSE), m_query_func(NULL), m_version_func(NULL)
611 { }
612 // destructor
613 ~Chuck_DLL() { this->unload(); }
614
615protected:
616 // data
617 void * m_handle;
618 std::string m_last_error;
619 std::string m_filename;
620 std::string m_id;
621 std::string m_func;
622 t_CKBOOL m_done_query;
623
624 f_ck_declversion m_version_func;
625 f_ck_query m_query_func;
626 Chuck_DL_Query m_query;
627};
628
629
630
631
632/* API to ChucK's innards */
633namespace Chuck_DL_Api
634{
635typedef void * Object;
636typedef void * Type;
637typedef void * String;
638
639struct Api
640{
641public:
642 static Api g_api;
643 static inline const Api * instance() { return &g_api; }
644
645 struct VMApi
646 {
647 VMApi();
648 t_CKUINT (* const get_srate)( CK_DL_API, Chuck_VM_Shred * );
649 } * const vm;
650
651 struct ObjectApi
652 {
653 ObjectApi();
654
655 private:
656 Type (* const get_type)( CK_DL_API, Chuck_VM_Shred *, std::string &name );
657
658 Object (* const create)( CK_DL_API, Chuck_VM_Shred *, Type type );
659
660 String (* const create_string)( CK_DL_API, Chuck_VM_Shred *, std::string &value );
661
662 t_CKBOOL (* const get_mvar_int)( CK_DL_API, Object object, std::string &name, t_CKINT &value );
663 t_CKBOOL (* const get_mvar_float)( CK_DL_API, Object object, std::string &name, t_CKFLOAT &value );
664 t_CKBOOL (* const get_mvar_dur)( CK_DL_API, Object object, std::string &name, t_CKDUR &value );
665 t_CKBOOL (* const get_mvar_time)( CK_DL_API, Object object, std::string &name, t_CKTIME &value );
666 t_CKBOOL (* const get_mvar_string)( CK_DL_API, Object object, std::string &name, String &value );
667 t_CKBOOL (* const get_mvar_object)( CK_DL_API, Object object, std::string &name, Object &value );
668
669 t_CKBOOL (* const set_string)( CK_DL_API, String string, std::string &value );
670
671 } * const object;
672
673 Api() :
674 vm(new VMApi),
675 object(new ObjectApi)
676 {}
677
678private:
679 Api(Api &a) :
680 vm(a.vm),
681 object(a.object)
682 { assert(0); };
683
684 Api &operator=(Api &a) { assert(0); return a; }
685};
686}
687
688
689
690// dlfcn interface
691#if defined(__MACOSX_CORE__)
692#include <AvailabilityMacros.h>
693#endif
694
695// dlfcn interface, panther or below
696#if defined(__MACOSX_CORE__) && MAC_OS_X_VERSION_MAX_ALLOWED <= 1030
697
698#error ChucK not support on Mac OS X 10.3 or lower
699
700#elif defined(__WINDOWS_DS__) || defined(__WINDOWS_ASIO__)
701
702 #ifdef __cplusplus
703 extern "C" {
704 #endif
705
706 #define RTLD_LAZY 0x1
707 #define RTLD_NOW 0x2
708 #define RTLD_LOCAL 0x4
709 #define RTLD_GLOBAL 0x8
710 #define RTLD_NOLOAD 0x10
711 #define RTLD_SHARED 0x20 /* not used, the default */
712 #define RTLD_UNSHARED 0x40
713 #define RTLD_NODELETE 0x80
714 #define RTLD_LAZY_UNDEF 0x100
715
716 void * dlopen( const char * path, int mode );
717 void * dlsym( void * handle, const char * symbol );
718 const char * dlerror( void );
719 int dlclose( void * handle );
720 static char dlerror_buffer[128];
721
722 #ifdef __cplusplus
723 }
724 #endif
725
726#else
727 #include "dlfcn.h"
728#endif
729
730
731
732#endif
core/chuck_emit.cpp+0−5072
@@ -1,5072 +0,0 @@
1/*----------------------------------------------------------------------------
2 ChucK Concurrent, On-the-fly Audio Programming Language
3 Compiler and Virtual Machine
4
5 Copyright (c) 2004 Ge Wang and Perry R. Cook. All rights reserved.
6 http://chuck.stanford.edu/
7 http://chuck.cs.princeton.edu/
8
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.
13
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.
18
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-----------------------------------------------------------------------------*/
24
25//-----------------------------------------------------------------------------
26// file: chuck_emit.cpp
27// desc: chuck instruction emitter
28//
29// author: Ge Wang (ge@ccrma.stanford.edu | gewang@cs.princeton.edu)
30// date: Autumn 2002 - first version
31// Autumn 2004 - redesign
32//-----------------------------------------------------------------------------
33#include "chuck_emit.h"
34#include "chuck_vm.h"
35#include "chuck_errmsg.h"
36#include "chuck_instr.h"
37#include <sstream>
38#include <iostream>
39
40using namespace std;
41
42
43
44
45//-----------------------------------------------------------------------------
46// function prototypes
47//-----------------------------------------------------------------------------
48t_CKBOOL emit_engine_emit_stmt_list( Chuck_Emitter * emit, a_Stmt_List list );
49t_CKBOOL emit_engine_emit_stmt( Chuck_Emitter * emit, a_Stmt stmt, t_CKBOOL pop = TRUE );
50t_CKBOOL emit_engine_emit_if( Chuck_Emitter * emit, a_Stmt_If stmt );
51t_CKBOOL emit_engine_emit_for( Chuck_Emitter * emit, a_Stmt_For stmt );
52t_CKBOOL emit_engine_emit_while( Chuck_Emitter * emit, a_Stmt_While stmt );
53t_CKBOOL emit_engine_emit_do_while( Chuck_Emitter * emit, a_Stmt_While stmt );
54t_CKBOOL emit_engine_emit_until( Chuck_Emitter * emit, a_Stmt_Until stmt );
55t_CKBOOL emit_engine_emit_do_until( Chuck_Emitter * emit, a_Stmt_Until stmt );
56t_CKBOOL emit_engine_emit_loop( Chuck_Emitter * emit, a_Stmt_Loop stmt );
57t_CKBOOL emit_engine_emit_break( Chuck_Emitter * emit, a_Stmt_Break br );
58t_CKBOOL emit_engine_emit_continue( Chuck_Emitter * emit, a_Stmt_Continue cont );
59t_CKBOOL emit_engine_emit_return( Chuck_Emitter * emit, a_Stmt_Return stmt );
60t_CKBOOL emit_engine_emit_switch( Chuck_Emitter * emit, a_Stmt_Switch stmt );
61t_CKBOOL emit_engine_emit_exp( Chuck_Emitter * emit, a_Exp exp, t_CKBOOL doAddRef = FALSE );
62t_CKBOOL emit_engine_emit_exp_binary( Chuck_Emitter * emit, a_Exp_Binary binary );
63t_CKBOOL emit_engine_emit_op( Chuck_Emitter * emit, ae_Operator op, a_Exp lhs, a_Exp rhs, a_Exp_Binary binary );
64t_CKBOOL emit_engine_emit_op_chuck( Chuck_Emitter * emit, a_Exp lhs, a_Exp rhs, a_Exp_Binary binary );
65t_CKBOOL emit_engine_emit_op_unchuck( Chuck_Emitter * emit, a_Exp lhs, a_Exp rhs );
66t_CKBOOL emit_engine_emit_op_upchuck( Chuck_Emitter * emit, a_Exp lhs, a_Exp rhs );
67t_CKBOOL emit_engine_emit_op_at_chuck( Chuck_Emitter * emit, a_Exp lhs, a_Exp rhs );
68t_CKBOOL emit_engine_emit_exp_unary( Chuck_Emitter * emit, a_Exp_Unary unary );
69t_CKBOOL emit_engine_emit_exp_primary( Chuck_Emitter * emit, a_Exp_Primary exp );
70t_CKBOOL emit_engine_emit_exp_cast( Chuck_Emitter * emit, a_Exp_Cast cast );
71t_CKBOOL emit_engine_emit_exp_postfix( Chuck_Emitter * emit, a_Exp_Postfix postfix );
72t_CKBOOL emit_engine_emit_exp_dur( Chuck_Emitter * emit, a_Exp_Dur dur );
73t_CKBOOL emit_engine_emit_exp_array( Chuck_Emitter * emit, a_Exp_Array array );
74t_CKBOOL emit_engine_emit_exp_func_call( Chuck_Emitter * emit, Chuck_Func * func,
75 Chuck_Type * type, int linepos, t_CKBOOL spork = FALSE );
76t_CKBOOL emit_engine_emit_exp_func_call( Chuck_Emitter * emit, a_Exp_Func_Call func_call,
77 t_CKBOOL spork = FALSE );
78t_CKBOOL emit_engine_emit_func_args( Chuck_Emitter * emit, a_Exp_Func_Call func_call );
79t_CKBOOL emit_engine_emit_exp_dot_member( Chuck_Emitter * emit, a_Exp_Dot_Member member );
80t_CKBOOL emit_engine_emit_exp_if( Chuck_Emitter * emit, a_Exp_If exp_if );
81t_CKBOOL emit_engine_emit_exp_decl( Chuck_Emitter * emit, a_Exp_Decl decl, t_CKBOOL first_exp );
82t_CKBOOL emit_engine_emit_array_lit( Chuck_Emitter * emit, a_Array_Sub array );
83t_CKBOOL emit_engine_emit_complex_lit( Chuck_Emitter * emit, a_Complex val );
84t_CKBOOL emit_engine_emit_polar_lit( Chuck_Emitter * emit, a_Polar val );
85t_CKBOOL emit_engine_emit_vec_lit( Chuck_Emitter * emit, a_Vec val );
86t_CKBOOL emit_engine_emit_code_segment( Chuck_Emitter * emit, a_Stmt_Code stmt,
87 t_CKBOOL push = TRUE );
88t_CKBOOL emit_engine_emit_func_def( Chuck_Emitter * emit, a_Func_Def func_def );
89t_CKBOOL emit_engine_emit_class_def( Chuck_Emitter * emit, a_Class_Def class_def );
90t_CKBOOL emit_engine_pre_constructor( Chuck_Emitter * emit, Chuck_Type * type );
91t_CKBOOL emit_engine_instantiate_object( Chuck_Emitter * emit, Chuck_Type * type,
92 a_Array_Sub array, t_CKBOOL is_ref );
93t_CKBOOL emit_engine_emit_spork( Chuck_Emitter * emit, a_Exp_Func_Call exp );
94t_CKBOOL emit_engine_emit_cast( Chuck_Emitter * emit, Chuck_Type * to, Chuck_Type * from );
95t_CKBOOL emit_engine_emit_symbol( Chuck_Emitter * emit, S_Symbol symbol,
96 Chuck_Value * v, t_CKBOOL emit_var, int linepos );
97// disabled until further notice (added 1.3.0.0)
98// t_CKBOOL emit_engine_emit_spork( Chuck_Emitter * emit, a_Stmt stmt );
99
100
101
102
103//-----------------------------------------------------------------------------
104// name: emit_engine_init()
105// desc: ...
106//-----------------------------------------------------------------------------
107Chuck_Emitter * emit_engine_init( Chuck_Env * env )
108{
109 // log
110 EM_log( CK_LOG_SEVERE, "initializing emitter..." );
111
112 // TODO: ensure this in a better way
113 assert( sizeof(t_CKUINT) == sizeof(void *) );
114
115 // allocate new emit
116 Chuck_Emitter * emit = new Chuck_Emitter;
117 // set the reference
118 emit->env = env;
119
120 return emit;
121}
122
123
124
125
126//-----------------------------------------------------------------------------
127// name: emit_engine_shutdown()
128// desc: ...
129//-----------------------------------------------------------------------------
130t_CKBOOL emit_engine_shutdown( Chuck_Emitter *& emit )
131{
132 if( !emit ) return FALSE;
133
134 // log
135 EM_log( CK_LOG_SYSTEM, "shutting down emitter..." );
136
137 // delete
138 delete emit;
139 emit = NULL;
140
141 return TRUE;
142}
143
144
145
146
147//-----------------------------------------------------------------------------
148// name: emit_engine_emit_prog()
149// desc: ...
150//-----------------------------------------------------------------------------
151Chuck_VM_Code * emit_engine_emit_prog( Chuck_Emitter * emit, a_Program prog,
152 te_HowMuch how_much )
153{
154 // make sure the code is NULL
155 assert( emit->code == NULL );
156 // make sure the stack is empty
157 assert( emit->stack.size() == 0 );
158 // make sure there is a context to emit
159 assert( emit->env->context != NULL );
160 // make sure no code
161 assert( emit->env->context->nspc->pre_ctor == NULL );
162
163 // log
164 EM_log( CK_LOG_FINER, "(pass 4) emitting VM code '%s'...",
165 emit->env->context->filename.c_str() );
166 // push indent
167 EM_pushlog();
168 // log how much
169 EM_log( CK_LOG_FINER, "target: %s", howmuch2str( how_much ) );
170
171 // return
172 t_CKBOOL ret = TRUE;
173 // allocate the code
174 emit->code = new Chuck_Code;
175 // set the current context
176 emit->context = emit->env->context;
177 // set the namespace
178 emit->nspc = emit->context->nspc;
179 // reset the func
180 emit->func = NULL;
181 // clear the code stack
182 emit->stack.clear();
183 // name the code
184 // emit->code->name = "(main)";
185 // whether code need this
186 emit->code->need_this = TRUE;
187 // keep track of full path (added 1.3.0.0)
188 emit->code->filename = emit->context->full_path;
189 // push global scope (added 1.3.0.0)
190 emit->push_scope();
191
192 // loop over the program sections
193 while( prog && ret )
194 {
195 switch( prog->section->s_type )
196 {
197 case ae_section_stmt: // code section
198 // if only classes, then skip
199 if( how_much == te_do_classes_only ) break;
200 // emit statement list
201 ret = emit_engine_emit_stmt_list( emit, prog->section->stmt_list );
202 break;
203
204 case ae_section_func: // function definition
205 // if only classes, then skip
206 if( how_much == te_do_classes_only ) break;
207 // check function definition
208 ret = emit_engine_emit_func_def( emit, prog->section->func_def );
209 break;
210
211 case ae_section_class: // class definition
212 // if no classes, then skip
213 if( how_much == te_do_no_classes ) break;
214 // check class definition
215 ret = emit_engine_emit_class_def( emit, prog->section->class_def );
216 break;
217
218 default: // bad
219 EM_error2( 0,
220 "internal compiler error: unrecognized program section..." );
221 ret = FALSE;
222 break;
223 }
224
225 // the next
226 prog = prog->next;
227 }
228
229 if( ret )
230 {
231 // pop global scope (added 1.3.0.0)
232 emit->pop_scope();
233 // append end of code
234 emit->append( new Chuck_Instr_EOC );
235 // make sure
236 assert( emit->context->nspc->pre_ctor == NULL );
237 // converted to virtual machine code
238 emit->context->nspc->pre_ctor = emit_to_code( emit->code, NULL, emit->dump );
239 // add reference
240 emit->context->nspc->pre_ctor->add_ref();
241 }
242
243 // clear the code
244 delete emit->code;
245 emit->code = NULL;
246
247 // pop indent
248 EM_poplog();
249
250 // return the code
251 return emit->context->nspc->pre_ctor;
252}
253
254
255
256
257//-----------------------------------------------------------------------------
258// name: emit_to_code()
259// desc: ...
260//-----------------------------------------------------------------------------
261Chuck_VM_Code * emit_to_code( Chuck_Code * in,
262 Chuck_VM_Code * out,
263 t_CKBOOL dump )
264{
265 // log
266 EM_log( CK_LOG_FINER, "emitting code: %d VM instructions...",
267 in->code.size() );
268 // allocate the vm code
269 Chuck_VM_Code * code = out ? out : new Chuck_VM_Code;
270 // make sure
271 assert( code->num_instr == 0 );
272 // size
273 code->num_instr = in->code.size();
274 // allocate instruction pointers+
275 code->instr = new Chuck_Instr *[code->num_instr];
276 // set the stack depth
277 code->stack_depth = in->stack_depth;
278 // set whether code need this base pointer
279 code->need_this = in->need_this;
280 // set name
281 code->name = in->name;
282 // set filename for me.sourceDir() (added 1.3.0.0)
283 code->filename = in->filename;
284
285 // copy
286 for( t_CKUINT i = 0; i < code->num_instr; i++ )
287 code->instr[i] = in->code[i];
288
289 // dump
290 if( dump )
291 {
292 // name of what we are dumping
293 EM_error2( 0, "dumping %s:", in->name.c_str() );
294
295 // uh
296 EM_error2( 0, "-------" );
297 for( t_CKUINT i = 0; i < code->num_instr; i++ )
298 EM_error2( 0, "[%i] %s( %s )", i,
299 code->instr[i]->name(), code->instr[i]->params() );
300 EM_error2( 0, "-------\n" );
301 }
302
303 return code;
304}
305
306
307
308
309//-----------------------------------------------------------------------------
310// name:
311// desc: ...
312//-----------------------------------------------------------------------------
313// t_CKBOOL emit_engine_addr_map( Chuck_Emitter * emit, Chuck_VM_Shred * shred );
314
315
316
317
318//-----------------------------------------------------------------------------
319// name:
320// desc: ...
321//-----------------------------------------------------------------------------
322// t_CKBOOL emit_engine_resolve( );
323
324
325
326
327//-----------------------------------------------------------------------------
328// name: emit_engine_emit_stmt_list()
329// desc: ...
330//-----------------------------------------------------------------------------
331t_CKBOOL emit_engine_emit_stmt_list( Chuck_Emitter * emit, a_Stmt_List list )
332{
333 t_CKBOOL ret = TRUE;
334
335 // emit->push();
336 while( list && ret )
337 {
338 ret = emit_engine_emit_stmt( emit, list->stmt );
339 list = list->next;
340 }
341 // emit->pop();
342
343 return ret;
344}
345
346
347
348
349//-----------------------------------------------------------------------------
350// name: emit_engine_emit_stmt()
351// desc: ...
352//-----------------------------------------------------------------------------
353t_CKBOOL emit_engine_emit_stmt( Chuck_Emitter * emit, a_Stmt stmt, t_CKBOOL pop )
354{
355 // empty stmt list
356 if( !stmt )
357 return TRUE;
358
359 // return
360 t_CKBOOL ret = TRUE;
361
362 // loop over statements
363 switch( stmt->s_type )
364 {
365 case ae_stmt_exp: // expression statement
366 // emit it
367 ret = emit_engine_emit_exp( emit, stmt->stmt_exp );
368 if( !ret )
369 return FALSE;
370 // need to pop the final value from stack
371 if( ret && pop && stmt->stmt_exp->type->size > 0 )
372 {
373 // sanity
374 assert( stmt->stmt_exp->cast_to == NULL );
375
376 // exp
377 a_Exp exp = stmt->stmt_exp;
378 // hack
379 if( exp->s_type == ae_exp_primary && exp->primary.s_type == ae_primary_hack )
380 exp = exp->primary.exp;
381
382 // HACK!
383 while( exp )
384 {
385 // if decl, then expect only one word per var
386 // added 1.3.1.0: iskindofint -- since on some 64-bit systems sz_INT == sz_FLOAT
387 if( exp->s_type == ae_exp_decl )
388 // (added 1.3.1.0 -- multiply by type size; #64-bit)
389 // (fixed 1.3.1.2 -- uh... decl should also be int-sized, so changed to INT/WORD)
390 emit->append( new Chuck_Instr_Reg_Pop_Word4( exp->decl.num_var_decls * sz_INT / sz_WORD ) );
391 else if( exp->type->size == sz_INT && iskindofint(emit->env, exp->type) ) // ISSUE: 64-bit (fixed 1.3.1.0)
392 emit->append( new Chuck_Instr_Reg_Pop_Word );
393 else if( exp->type->size == sz_FLOAT ) // ISSUE: 64-bit (fixed 1.3.1.0)
394 emit->append( new Chuck_Instr_Reg_Pop_Word2 );
395 else if( exp->type->size == sz_COMPLEX ) // ISSUE: 64-bit (fixed 1.3.1.0)
396 emit->append( new Chuck_Instr_Reg_Pop_Word3 );
397 else if( exp->type->size == sz_VEC3 ) // ge: added 1.3.5.3
398 emit->append( new Chuck_Instr_Reg_Pop_Word4(sz_VEC3/sz_WORD) );
399 else if( exp->type->size == sz_VEC4 ) // ge: added 1.3.5.3
400 emit->append( new Chuck_Instr_Reg_Pop_Word4(sz_VEC4/sz_WORD) );
401 else
402 {
403 EM_error2( exp->linepos,
404 "(emit): internal error: %i byte stack item unhandled...",
405 exp->type->size );
406 return FALSE;
407 }
408
409 // go
410 exp = exp->next;
411 }
412 }
413 break;
414
415 case ae_stmt_if: // if statement
416 ret = emit_engine_emit_if( emit, &stmt->stmt_if );
417 break;
418
419 case ae_stmt_for: // for statement
420 ret = emit_engine_emit_for( emit, &stmt->stmt_for );
421 break;
422
423 case ae_stmt_while: // while statement
424 if( stmt->stmt_while.is_do )
425 ret = emit_engine_emit_do_while( emit, &stmt->stmt_while );
426 else
427 ret = emit_engine_emit_while( emit, &stmt->stmt_while );
428 break;
429
430 case ae_stmt_until: // until statement
431 if( stmt->stmt_until.is_do )
432 ret = emit_engine_emit_do_until( emit, &stmt->stmt_until );
433 else
434 ret = emit_engine_emit_until( emit, &stmt->stmt_until );
435 break;
436
437 case ae_stmt_loop: // loop statement
438 ret = emit_engine_emit_loop( emit, &stmt->stmt_loop );
439 break;
440
441 case ae_stmt_switch: // switch statement
442 // not implemented
443 ret = FALSE;
444 break;
445
446 case ae_stmt_break: // break statement
447 ret = emit_engine_emit_break( emit, &stmt->stmt_break );
448 break;
449
450 case ae_stmt_code: // code segment
451 ret = emit_engine_emit_code_segment( emit, &stmt->stmt_code );
452 break;
453
454 case ae_stmt_continue: // continue statement
455 ret = emit_engine_emit_continue( emit, &stmt->stmt_continue );
456 break;
457
458 case ae_stmt_return: // return statement
459 ret = emit_engine_emit_return( emit, &stmt->stmt_return );
460 break;
461
462 case ae_stmt_case: // case statement
463 // not implemented
464 ret = FALSE;
465 // ret = emit_engine_emit_case( emit, &stmt->stmt_case );
466 break;
467
468 case ae_stmt_gotolabel: // goto label statement
469 // not implemented
470 ret = FALSE;
471 // ret = emit_engine_emit_gotolabel( emit, &stmt->stmt_case );
472 break;
473
474 default: // bad
475 EM_error2( stmt->linepos,
476 "(emit): internal error: unhandled statement type '%i'...",
477 stmt->s_type );
478 break;
479 }
480
481 return ret;
482}
483
484
485
486
487//-----------------------------------------------------------------------------
488// name: emit_engine_emit_if()
489// desc: ...
490//-----------------------------------------------------------------------------
491t_CKBOOL emit_engine_emit_if( Chuck_Emitter * emit, a_Stmt_If stmt )
492{
493 t_CKBOOL ret = TRUE;
494 Chuck_Instr_Branch_Op * op = NULL, * op2 = NULL;
495
496 // push the stack, allowing for new local variables
497 emit->push_scope();
498
499 // emit the condition
500 ret = emit_engine_emit_exp( emit, stmt->cond );
501 if( !ret )
502 return FALSE;
503
504 // type of the condition
505 switch( stmt->cond->type->xid )
506 {
507 case te_int:
508 // push 0
509 emit->append( new Chuck_Instr_Reg_Push_Imm( 0 ) );
510 op = new Chuck_Instr_Branch_Eq_int( 0 );
511 break;
512 case te_float:
513 case te_dur:
514 case te_time:
515 // push 0
516 emit->append( new Chuck_Instr_Reg_Push_Imm2( 0.0 ) );
517 op = new Chuck_Instr_Branch_Eq_double( 0 );
518 break;
519
520 default:
521 // check for IO
522 if( isa( stmt->cond->type, emit->env->t_io ) )
523 {
524 // push 0
525 emit->append( new Chuck_Instr_Reg_Push_Imm( 0 ) );
526 op = new Chuck_Instr_Branch_Eq_int_IO_good( 0 );
527 break;
528 }
529
530 EM_error2( stmt->cond->linepos,
531 "(emit): internal error: unhandled type '%s' in if condition",
532 stmt->cond->type->name.c_str() );
533 return FALSE;
534 }
535
536 if( !ret ) return FALSE;
537
538 // append the op
539 emit->append( op );
540
541 // ge: 2012 april: scope for if body (added 1.3.0.0)
542 {
543 // push the stack, allowing for new local variables
544 emit->push_scope();
545 // emit the body
546 ret = emit_engine_emit_stmt( emit, stmt->if_body );
547 if( !ret )
548 return FALSE;
549 // pop stack
550 emit->pop_scope();
551 }
552
553 // emit the skip to the end
554 emit->append( op2 = new Chuck_Instr_Goto(0) );
555
556 // set the op's target
557 op->set( emit->next_index() );
558
559 // ge: 2012 april: scope for else body (added 1.3.0.0)
560 {
561 // push the stack, allowing for new local variables
562 emit->push_scope();
563 // emit the body
564 ret = emit_engine_emit_stmt( emit, stmt->else_body );
565 if( !ret )
566 return FALSE;
567 // pop stack
568 emit->pop_scope();
569 }
570
571 // set the op2's target
572 op2->set( emit->next_index() );
573
574 // pop stack
575 emit->pop_scope();
576
577 return ret;
578}
579
580
581
582
583//-----------------------------------------------------------------------------
584// name: emit_engine_emit_for()
585// desc: ...
586//-----------------------------------------------------------------------------
587t_CKBOOL emit_engine_emit_for( Chuck_Emitter * emit, a_Stmt_For stmt )
588{
589 t_CKBOOL ret = TRUE;
590 Chuck_Instr_Branch_Op * op = NULL;
591
592 // push the stack
593 emit->push_scope();
594
595 // emit the cond
596 ret = emit_engine_emit_stmt( emit, stmt->c1 );
597 if( !ret )
598 return FALSE;
599
600 // the start index
601 t_CKUINT start_index = emit->next_index();
602 t_CKUINT cont_index = 0;
603 // mark the stack of continue
604 emit->code->stack_cont.push_back( NULL );
605 // mark the stack of break
606 emit->code->stack_break.push_back( NULL );
607
608 // emit the cond - keep the result on the stack
609 emit_engine_emit_stmt( emit, stmt->c2, FALSE );
610
611 // could be NULL
612 if( stmt->c2 )
613 {
614 switch( stmt->c2->stmt_exp->type->xid )
615 {
616 case te_int:
617 // push 0
618 emit->append( new Chuck_Instr_Reg_Push_Imm( 0 ) );
619 op = new Chuck_Instr_Branch_Eq_int( 0 );
620 break;
621 case te_float:
622 case te_dur:
623 case te_time:
624 // push 0
625 emit->append( new Chuck_Instr_Reg_Push_Imm2( 0.0 ) );
626 op = new Chuck_Instr_Branch_Eq_double( 0 );
627 break;
628
629 default:
630 // check for IO
631 if( isa( stmt->c2->stmt_exp->type, emit->env->t_io ) )
632 {
633 // push 0
634 emit->append( new Chuck_Instr_Reg_Push_Imm( 0 ) );
635 op = new Chuck_Instr_Branch_Eq_int_IO_good( 0 );
636 break;
637 }
638
639 EM_error2( stmt->c2->stmt_exp->linepos,
640 "(emit): internal error: unhandled type '%s' in for conditional",
641 stmt->c2->stmt_exp->type->name.c_str() );
642 return FALSE;
643 }
644 // append the op
645 emit->append( op );
646 }
647
648 // added 1.3.1.1: new scope just for loop body
649 emit->push_scope();
650
651 // emit the body
652 ret = emit_engine_emit_stmt( emit, stmt->body );
653 if( !ret )
654 return FALSE;
655
656 // added 1.3.1.1: pop scope for loop body
657 emit->pop_scope();
658
659 // continue here
660 cont_index = emit->next_index();
661
662 // emit the action
663 if( stmt->c3 )
664 {
665 ret = emit_engine_emit_exp( emit, stmt->c3 );
666 if( !ret )
667 return FALSE;
668
669 // HACK!
670 // count the number of words to pop
671 a_Exp e = stmt->c3;
672 t_CKUINT num_words = 0;
673 while( e )
674 {
675 if( e->type->size == sz_FLOAT ) // ISSUE: 64-bit (fixed 1.3.1.0)
676 num_words += sz_FLOAT / sz_WORD; // changed to compute number of words; 1.3.1.0
677 else if( e->type->size == sz_INT ) // ISSUE: 64-bit (fixed 1.3.1.0)
678 num_words += sz_INT / sz_WORD; // changed to compute number of words; 1.3.1.0
679 else if( e->type->size == sz_COMPLEX ) // ISSUE: 64-bit (fixed 1.3.1.0)
680 num_words += sz_COMPLEX / sz_WORD; // changed to compute number of words; 1.3.1.0
681 else if( e->type->size != 0 )
682 {
683 EM_error2( e->linepos,
684 "(emit): internal error: non-void type size %i unhandled...",
685 e->type->size );
686 return FALSE;
687 }
688
689 // advance
690 e = e->next;
691 }
692
693 // pop (changed to Chuck_Instr_Reg_Pop_Word4 in 1.3.1.0)
694 if( num_words > 0 ) emit->append( new Chuck_Instr_Reg_Pop_Word4( num_words ) );
695 }
696
697 // go back to do check the condition
698 emit->append( new Chuck_Instr_Goto( start_index ) );
699
700 // could be NULL
701 if( stmt->c2 )
702 // set the op's target
703 op->set( emit->next_index() );
704
705 // stack of continue
706 while( emit->code->stack_cont.size() && emit->code->stack_cont.back() )
707 {
708 emit->code->stack_cont.back()->set( cont_index );
709 emit->code->stack_cont.pop_back();
710 }
711
712 // stack of break
713 while( emit->code->stack_break.size() && emit->code->stack_break.back() )
714 {
715 emit->code->stack_break.back()->set( emit->next_index() );
716 emit->code->stack_break.pop_back();
717 }
718
719 // pop stack
720 emit->pop_scope();
721 // pop continue stack
722 emit->code->stack_cont.pop_back();
723 // pop break stack
724 emit->code->stack_break.pop_back();
725
726 return ret;
727}
728
729
730
731
732//-----------------------------------------------------------------------------
733// name: emit_engine_emit_while()
734// desc: ...
735//-----------------------------------------------------------------------------
736t_CKBOOL emit_engine_emit_while( Chuck_Emitter * emit, a_Stmt_While stmt )
737{
738 t_CKBOOL ret = TRUE;
739 Chuck_Instr_Branch_Op * op = NULL;
740
741 // push stack
742 emit->push_scope();
743
744 // get the index
745 t_CKUINT start_index = emit->next_index();
746 // mark the stack of continue
747 emit->code->stack_cont.push_back( NULL );
748 // mark the stack of break
749 emit->code->stack_break.push_back( NULL );
750
751 // emit the cond
752 ret = emit_engine_emit_exp( emit, stmt->cond );
753 if( !ret )
754 return FALSE;
755
756 // the condition
757 switch( stmt->cond->type->xid )
758 {
759 case te_int:
760 // push 0
761 emit->append( new Chuck_Instr_Reg_Push_Imm( 0 ) );
762 op = new Chuck_Instr_Branch_Eq_int( 0 );
763 break;
764 case te_float:
765 case te_dur:
766 case te_time:
767 // push 0
768 emit->append( new Chuck_Instr_Reg_Push_Imm2( 0.0 ) );
769 op = new Chuck_Instr_Branch_Eq_double( 0 );
770 break;
771
772 default:
773 // check for IO
774 if( isa( stmt->cond->type, emit->env->t_io ) )
775 {
776 // push 0
777 emit->append( new Chuck_Instr_Reg_Push_Imm( 0 ) );
778 op = new Chuck_Instr_Branch_Eq_int_IO_good( 0 );
779 break;
780 }
781
782 EM_error2( stmt->cond->linepos,
783 "(emit): internal error: unhandled type '%s' in while conditional",
784 stmt->cond->type->name.c_str() );
785 return FALSE;
786 }
787
788 // append the op
789 emit->append( op );
790
791 // added 1.3.1.1: new scope just for loop body
792 emit->push_scope();
793
794 // emit the body
795 ret = emit_engine_emit_stmt( emit, stmt->body );
796 if( !ret )
797 return FALSE;
798
799 // added 1.3.1.1: pop scope for loop body
800 emit->pop_scope();
801
802 // go back to do check the condition
803 emit->append( new Chuck_Instr_Goto( start_index ) );
804
805 // set the op's target
806 op->set( emit->next_index() );
807
808 // stack of continue
809 while( emit->code->stack_cont.size() && emit->code->stack_cont.back() )
810 {
811 emit->code->stack_cont.back()->set( start_index );
812 emit->code->stack_cont.pop_back();
813 }
814
815 // stack of break
816 while( emit->code->stack_break.size() && emit->code->stack_break.back() )
817 {
818 emit->code->stack_break.back()->set( emit->next_index() );
819 emit->code->stack_break.pop_back();
820 }
821
822 // pop stack
823 emit->pop_scope();
824 // pop continue stack
825 emit->code->stack_cont.pop_back();
826 // pop break stack
827 emit->code->stack_break.pop_back();
828
829 return ret;
830}
831
832
833
834
835//-----------------------------------------------------------------------------
836// name: emit_engine_emit_do_while()
837// desc: ...
838//-----------------------------------------------------------------------------
839t_CKBOOL emit_engine_emit_do_while( Chuck_Emitter * emit, a_Stmt_While stmt )
840{
841 t_CKBOOL ret = TRUE;
842 Chuck_Instr_Branch_Op * op = NULL;
843 t_CKUINT start_index = emit->next_index();
844
845 // push stack
846 emit->push_scope();
847
848 // mark the stack of continue
849 emit->code->stack_cont.push_back( NULL );
850 // mark the stack of break
851 emit->code->stack_break.push_back( NULL );
852
853 // added 1.3.1.1: new scope just for loop body
854 emit->push_scope();
855
856 // emit the body
857 ret = emit_engine_emit_stmt( emit, stmt->body );
858 if( !ret )
859 return FALSE;
860
861 // added 1.3.1.1: pop scope for loop body
862 emit->pop_scope();
863
864 // emit the cond
865 ret = emit_engine_emit_exp( emit, stmt->cond );
866 if( !ret )
867 return FALSE;
868
869 // the condition
870 switch( stmt->cond->type->xid )
871 {
872 case te_int:
873 // push 0
874 emit->append( new Chuck_Instr_Reg_Push_Imm( 0 ) );
875 op = new Chuck_Instr_Branch_Neq_int( 0 );
876 break;
877 case te_float:
878 case te_dur:
879 case te_time:
880 // push 0
881 emit->append( new Chuck_Instr_Reg_Push_Imm2( 0.0 ) );
882 op = new Chuck_Instr_Branch_Neq_double( 0 );
883 break;
884
885 default:
886 // check for IO
887 if( isa( stmt->cond->type, emit->env->t_io ) )
888 {
889 // push 0
890 emit->append( new Chuck_Instr_Reg_Push_Imm( 0 ) );
891 op = new Chuck_Instr_Branch_Eq_int_IO_good( 0 );
892 break;
893 }
894
895 EM_error2( stmt->cond->linepos,
896 "(emit): internal error: unhandled type '%s' in do/while conditional",
897 stmt->cond->type->c_name() );
898 return FALSE;
899 }
900
901 // append the op
902 emit->append( op );
903
904 // set the op's target
905 op->set( start_index );
906
907 // stack of continue
908 while( emit->code->stack_cont.size() && emit->code->stack_cont.back() )
909 {
910 emit->code->stack_cont.back()->set( start_index );
911 emit->code->stack_cont.pop_back();
912 }
913
914 // stack of break
915 while( emit->code->stack_break.size() && emit->code->stack_break.back() )
916 {
917 emit->code->stack_break.back()->set( emit->next_index() );
918 emit->code->stack_break.pop_back();
919 }
920
921 // pop stack
922 emit->pop_scope();
923 // pop continue stack
924 emit->code->stack_cont.pop_back();
925 // pop break stack
926 emit->code->stack_break.pop_back();
927
928 return ret;
929}
930
931
932
933
934//-----------------------------------------------------------------------------
935// name: emit_engine_emit_until()
936// desc: ...
937//-----------------------------------------------------------------------------
938t_CKBOOL emit_engine_emit_until( Chuck_Emitter * emit, a_Stmt_Until stmt )
939{
940 t_CKBOOL ret = TRUE;
941 Chuck_Instr_Branch_Op * op = NULL;
942
943 // push stack
944 emit->push_scope();
945
946 // get index
947 t_CKUINT start_index = emit->next_index();
948 // mark the stack of continue
949 emit->code->stack_cont.push_back( NULL );
950 // mark the stack of break
951 emit->code->stack_break.push_back( NULL );
952
953 // emit the cond
954 ret = emit_engine_emit_exp( emit, stmt->cond );
955 if( !ret )
956 return FALSE;
957
958 // condition
959 switch( stmt->cond->type->xid )
960 {
961 case te_int:
962 // push 0
963 emit->append( new Chuck_Instr_Reg_Push_Imm( 0 ) );
964 op = new Chuck_Instr_Branch_Neq_int( 0 );
965 break;
966 case te_float:
967 case te_dur:
968 case te_time:
969 // push 0
970 emit->append( new Chuck_Instr_Reg_Push_Imm2( 0.0 ) );
971 op = new Chuck_Instr_Branch_Neq_double( 0 );
972 break;
973
974 default:
975 // check for IO
976 if( isa( stmt->cond->type, emit->env->t_io ) )
977 {
978 // push 0
979 emit->append( new Chuck_Instr_Reg_Push_Imm( 0 ) );
980 op = new Chuck_Instr_Branch_Neq_int_IO_good( 0 );
981 break;
982 }
983
984 EM_error2( stmt->cond->linepos,
985 "(emit): internal error: unhandled type '%s' in until conditional",
986 stmt->cond->type->name.c_str() );
987 return FALSE;
988 }
989
990 // append the op
991 emit->append( op );
992
993 // added 1.3.1.1: new scope just for loop body
994 emit->push_scope();
995
996 // emit the body
997 emit_engine_emit_stmt( emit, stmt->body );
998
999 // added 1.3.1.1: pop scope for loop body
1000 emit->pop_scope();
1001
1002 // go back to do check the condition
1003 emit->append( new Chuck_Instr_Goto( start_index ) );
1004
1005 // set the op's target
1006 op->set( emit->next_index() );
1007
1008 // stack of continue
1009 while( emit->code->stack_cont.size() && emit->code->stack_cont.back() )
1010 {
1011 emit->code->stack_cont.back()->set( start_index );
1012 emit->code->stack_cont.pop_back();
1013 }
1014
1015 // stack of break
1016 while( emit->code->stack_break.size() && emit->code->stack_break.back() )
1017 {
1018 emit->code->stack_break.back()->set( emit->next_index() );
1019 emit->code->stack_break.pop_back();
1020 }
1021
1022 // pop stack
1023 emit->pop_scope();
1024 // pop continue stack
1025 emit->code->stack_cont.pop_back();
1026 // pop break stack
1027 emit->code->stack_break.pop_back();
1028
1029 return ret;
1030}
1031
1032
1033
1034
1035//-----------------------------------------------------------------------------
1036// name: emit_engine_emit_do_until()
1037// desc: ...
1038//-----------------------------------------------------------------------------
1039t_CKBOOL emit_engine_emit_do_until( Chuck_Emitter * emit, a_Stmt_Until stmt )
1040{
1041 t_CKBOOL ret = TRUE;
1042 Chuck_Instr_Branch_Op * op = NULL;
1043
1044 // push stack
1045 emit->push_scope();
1046
1047 // the index
1048 t_CKUINT start_index = emit->next_index();
1049 // mark the stack of continue
1050 emit->code->stack_cont.push_back( NULL );
1051 // mark the stack of break
1052 emit->code->stack_break.push_back( NULL );
1053
1054 // added 1.3.1.1: new scope just for loop body
1055 emit->push_scope();
1056
1057 // emit the body
1058 ret = emit_engine_emit_stmt( emit, stmt->body );
1059 if( !ret )
1060 return FALSE;
1061
1062 // added 1.3.1.1: pop scope for loop body
1063 emit->pop_scope();
1064
1065 // emit the cond
1066 ret = emit_engine_emit_exp( emit, stmt->cond );
1067 if( !ret )
1068 return FALSE;
1069
1070 // condition
1071 switch( stmt->cond->type->xid )
1072 {
1073 case te_int:
1074 // push 0
1075 emit->append( new Chuck_Instr_Reg_Push_Imm( 0 ) );
1076 op = new Chuck_Instr_Branch_Eq_int( 0 );
1077 break;
1078 case te_float:
1079 case te_dur:
1080 case te_time:
1081 // push 0
1082 emit->append( new Chuck_Instr_Reg_Push_Imm2( 0.0 ) );
1083 op = new Chuck_Instr_Branch_Eq_double( 0 );
1084 break;
1085
1086 default:
1087 EM_error2( stmt->cond->linepos,
1088 "(emit): internal error: unhandled type '%s' in do/until conditional",
1089 stmt->cond->type->name.c_str() );
1090 return FALSE;
1091 }
1092
1093 // append the op
1094 emit->append( op );
1095
1096 // set the op's target
1097 op->set( start_index );
1098
1099 // stack of continue
1100 while( emit->code->stack_cont.size() && emit->code->stack_cont.back() )
1101 {
1102 emit->code->stack_cont.back()->set( start_index );
1103 emit->code->stack_cont.pop_back();
1104 }
1105
1106 // stack of break
1107 while( emit->code->stack_break.size() && emit->code->stack_break.back() )
1108 {
1109 emit->code->stack_break.back()->set( emit->next_index() );
1110 emit->code->stack_break.pop_back();
1111 }
1112
1113 // pop stack
1114 emit->pop_scope();
1115 // pop continue stack
1116 emit->code->stack_cont.pop_back();
1117 // pop break stack
1118 emit->code->stack_break.pop_back();
1119
1120 return ret;
1121}
1122
1123
1124
1125
1126//-----------------------------------------------------------------------------
1127// name: emit_engine_emit_loop()
1128// desc: ...
1129//-----------------------------------------------------------------------------
1130t_CKBOOL emit_engine_emit_loop( Chuck_Emitter * emit, a_Stmt_Loop stmt )
1131{
1132 t_CKBOOL ret = TRUE;
1133 Chuck_Instr_Branch_Op * op = NULL;
1134
1135 Chuck_Instr * instr = NULL;
1136
1137 // push stack
1138 emit->push_scope();
1139
1140 // emit the cond
1141 ret = emit_engine_emit_exp( emit, stmt->cond );
1142 if( !ret )
1143 return FALSE;
1144
1145 // initialize our loop counter (1.3.5.3)
1146 emit->append( new Chuck_Instr_Init_Loop_Counter() );
1147
1148 // get the index
1149 t_CKUINT start_index = emit->next_index();
1150 // mark the stack of continue
1151 emit->code->stack_cont.push_back( NULL );
1152 // mark the stack of break
1153 emit->code->stack_break.push_back( NULL );
1154
1155 // push the value of the loop counter
1156 emit->append( instr = new Chuck_Instr_Reg_Push_Loop_Counter_Deref() );
1157 instr->set_linepos( stmt->linepos );
1158
1159 // get the type, taking cast into account
1160 Chuck_Type * type = stmt->cond->cast_to ? stmt->cond->cast_to : stmt->cond->type;
1161
1162 // the condition
1163 switch( type->xid )
1164 {
1165 case te_int:
1166 // push 0
1167 emit->append( new Chuck_Instr_Reg_Push_Imm( 0 ) );
1168 op = new Chuck_Instr_Branch_Eq_int( 0 );
1169 break;
1170
1171 default:
1172 EM_error2( stmt->cond->linepos,
1173 "(emit): internal error: unhandled type '%s' in while conditional",
1174 type->name.c_str() );
1175
1176 return FALSE;
1177 }
1178
1179 // append the op
1180 emit->append( op );
1181
1182 // decrement the counter
1183 emit->append( instr = new Chuck_Instr_Dec_Loop_Counter() );
1184 instr->set_linepos( stmt->linepos );
1185
1186 // added 1.3.1.1: new scope just for loop body
1187 emit->push_scope();
1188
1189 // emit the body
1190 ret = emit_engine_emit_stmt( emit, stmt->body );
1191 if( !ret )
1192 return FALSE;
1193
1194 // added 1.3.1.1: pop scope for loop body
1195 emit->pop_scope();
1196
1197 // go back to do check the condition
1198 emit->append( new Chuck_Instr_Goto( start_index ) );
1199
1200 // set the op's target
1201 op->set( emit->next_index() );
1202
1203 // pop the loop counter
1204 emit->append( new Chuck_Instr_Pop_Loop_Counter );
1205
1206 // stack of continue
1207 while( emit->code->stack_cont.size() && emit->code->stack_cont.back() )
1208 {
1209 emit->code->stack_cont.back()->set( start_index );
1210 emit->code->stack_cont.pop_back();
1211 }
1212
1213 // stack of break
1214 while( emit->code->stack_break.size() && emit->code->stack_break.back() )
1215 {
1216 emit->code->stack_break.back()->set( emit->next_index() );
1217 emit->code->stack_break.pop_back();
1218 }
1219
1220 // pop stack
1221 emit->pop_scope();
1222 // pop continue stack
1223 emit->code->stack_cont.pop_back();
1224 // pop break stack
1225 emit->code->stack_break.pop_back();
1226
1227 return ret;
1228}
1229
1230
1231
1232
1233//-----------------------------------------------------------------------------
1234// name: emit_engine_emit_break()
1235// desc: ...
1236//-----------------------------------------------------------------------------
1237t_CKBOOL emit_engine_emit_break( Chuck_Emitter * emit, a_Stmt_Break br )
1238{
1239 // append
1240 Chuck_Instr_Goto * op = new Chuck_Instr_Goto( 0 );
1241 emit->append( op );
1242 // remember
1243 emit->code->stack_break.push_back( op );
1244
1245 return TRUE;
1246}
1247
1248
1249
1250
1251//-----------------------------------------------------------------------------
1252// name: emit_engine_emit_continue()
1253// desc: ...
1254//-----------------------------------------------------------------------------
1255t_CKBOOL emit_engine_emit_continue( Chuck_Emitter * emit, a_Stmt_Continue cont )
1256{
1257 // append
1258 Chuck_Instr_Goto * op = new Chuck_Instr_Goto( 0 );
1259 emit->append( op );
1260 // remember
1261 emit->code->stack_cont.push_back( op );
1262
1263 return TRUE;
1264}
1265
1266
1267
1268
1269//-----------------------------------------------------------------------------
1270// name: emit_engine_emit_return()
1271// desc: ...
1272//-----------------------------------------------------------------------------
1273t_CKBOOL emit_engine_emit_return( Chuck_Emitter * emit, a_Stmt_Return stmt )
1274{
1275 if( !emit_engine_emit_exp( emit, stmt->val ) )
1276 return FALSE;
1277
1278 // emit return
1279 // emit->append( new Chuck_Instr_Func_Return );
1280
1281 // determine where later
1282 Chuck_Instr_Goto * instr = new Chuck_Instr_Goto( 0 );
1283 emit->append( instr );
1284 emit->code->stack_return.push_back( instr );
1285
1286 return TRUE;
1287}
1288
1289
1290
1291
1292//-----------------------------------------------------------------------------
1293// name:
1294// desc: ...
1295//-----------------------------------------------------------------------------
1296t_CKBOOL emit_engine_emit_switch( Chuck_Emitter * emit, a_Stmt_Switch stmt );
1297
1298
1299
1300
1301//-----------------------------------------------------------------------------
1302// name: emit_engine_emit_exp()
1303// desc: (doAddRef added 1.3.0.0 -- typically this is set to TRUE for function
1304// calls so that pointers on the reg is accounted for; this is important
1305// in case the object is released/reclaimed before the value is used;
1306// on particular case is when sporking with a local object as argument)
1307//-----------------------------------------------------------------------------
1308t_CKBOOL emit_engine_emit_exp( Chuck_Emitter * emit, a_Exp exp, t_CKBOOL doAddRef )
1309{
1310 // for now...
1311 // assert( exp->next == NULL );
1312
1313 // loop over
1314 while( exp )
1315 {
1316 switch( exp->s_type )
1317 {
1318 case ae_exp_binary:
1319 if( !emit_engine_emit_exp_binary( emit, &exp->binary ) )
1320 return FALSE;
1321 break;
1322
1323 case ae_exp_unary:
1324 if( !emit_engine_emit_exp_unary( emit, &exp->unary ) )
1325 return FALSE;
1326 break;
1327
1328 case ae_exp_cast:
1329 if( !emit_engine_emit_exp_cast( emit, &exp->cast ) )
1330 return FALSE;
1331 break;
1332
1333 case ae_exp_postfix:
1334 if( !emit_engine_emit_exp_postfix( emit, &exp->postfix ) )
1335 return FALSE;
1336 break;
1337
1338 case ae_exp_dur:
1339 if( !emit_engine_emit_exp_dur( emit, &exp->dur ) )
1340 return FALSE;
1341 break;
1342
1343 case ae_exp_primary:
1344 if( !emit_engine_emit_exp_primary( emit, &exp->primary ) )
1345 return FALSE;
1346 break;
1347
1348 case ae_exp_array:
1349 if( !emit_engine_emit_exp_array( emit, &exp->array ) )
1350 return FALSE;
1351 break;
1352
1353 case ae_exp_func_call:
1354 if( !emit_engine_emit_exp_func_call( emit, &exp->func_call ) )
1355 return FALSE;
1356 break;
1357
1358 case ae_exp_dot_member:
1359 if( !emit_engine_emit_exp_dot_member( emit, &exp->dot_member ) )
1360 return FALSE;
1361 break;
1362
1363 case ae_exp_if:
1364 if( !emit_engine_emit_exp_if( emit, &exp->exp_if ) )
1365 return FALSE;
1366 break;
1367
1368 case ae_exp_decl:
1369 if( !emit_engine_emit_exp_decl( emit, &exp->decl, FALSE ) )
1370 return FALSE;
1371 break;
1372
1373 //case ae_exp_namespace:
1374 // if( !emit_engine_emit_exp_namespace( emit, &exp->name_space ) )
1375 // return FALSE;
1376 // break;
1377
1378 default:
1379 EM_error2( exp->linepos,
1380 "(emit): internal error: unhandled expression type '%i'...",
1381 exp->s_type );
1382 return FALSE;
1383 }
1384
1385 // implicit cast
1386 if( exp->cast_to != NULL )
1387 if( !emit_engine_emit_cast( emit, exp->cast_to, exp->type ) )
1388 return FALSE;
1389
1390 // check if we need to handle ref (added 1.3.0.0)
1391 // (NOTE: cast shouldn't matter since pointer width should remain constant)
1392 if( doAddRef && isobj( emit->env, exp->type ) )
1393 {
1394 // add ref in place on the stack
1395 emit->append( new Chuck_Instr_Reg_AddRef_Object3() );
1396 }
1397
1398 exp = exp->next;
1399 }
1400
1401 return TRUE;
1402}
1403
1404
1405
1406
1407//-----------------------------------------------------------------------------
1408// name: emit_engine_emit_exp_binary()
1409// desc: ...
1410//-----------------------------------------------------------------------------
1411t_CKBOOL emit_engine_emit_exp_binary( Chuck_Emitter * emit, a_Exp_Binary binary )
1412{
1413 // sanity
1414 assert( binary->self->emit_var == FALSE );
1415
1416 t_CKBOOL left = FALSE;
1417 t_CKBOOL right = FALSE;
1418
1419 // hack to allow && to terminate as soon as possible - spencer
1420 // i.e. in ( 0 && f() ) the function f() will not be called
1421 // (obviates need for boolean AND instruction)
1422 if( binary->op == ae_op_and )
1423 {
1424 Chuck_Instr_Branch_Op * op;
1425
1426 // push default result
1427 emit->append( new Chuck_Instr_Reg_Push_Imm( 0 ) );
1428
1429 left = emit_engine_emit_exp( emit, binary->lhs );
1430 if( !left )
1431 return FALSE;
1432
1433 // compare to 0; use default result if zero
1434 emit->append( new Chuck_Instr_Reg_Push_Imm( 0 ) );
1435 emit->append( op = new Chuck_Instr_Branch_Eq_int( 0 ) );
1436
1437 // pop default result
1438 emit->append( new Chuck_Instr_Reg_Pop_Word );
1439
1440 // result of whole expression is now result of rhs
1441 right = emit_engine_emit_exp( emit, binary->rhs );
1442 if( !right )
1443 return FALSE;
1444
1445 // set branch location
1446 op->set( emit->next_index() );
1447
1448 return TRUE;
1449 }
1450
1451 // hack to allow || to terminate as soon as possible - spencer
1452 // i.e. in ( 1 || f() ) the function f() will not be called
1453 // (obviates need for boolean OR instruction)
1454 else if( binary->op == ae_op_or )
1455 {
1456 Chuck_Instr_Branch_Op * op;
1457
1458 // push default result
1459 emit->append( new Chuck_Instr_Reg_Push_Imm( 1 ) );
1460
1461 left = emit_engine_emit_exp( emit, binary->lhs );
1462 if( !left )
1463 return FALSE;
1464
1465 // compare to 0; use default result if non-zero
1466 emit->append( new Chuck_Instr_Reg_Push_Imm( 0 ) );
1467 emit->append( op = new Chuck_Instr_Branch_Neq_int( 0 ) );
1468
1469 // pop default result
1470 emit->append( new Chuck_Instr_Reg_Pop_Word );
1471
1472 // result of whole expression is now result of rhs
1473 right = emit_engine_emit_exp( emit, binary->rhs );
1474 if( !right )
1475 return FALSE;
1476
1477 // set branch location
1478 op->set( emit->next_index() );
1479
1480 return TRUE;
1481 }
1482
1483 // whether to track object references on stack (added 1.3.0.2)
1484 t_CKBOOL doRef = FALSE;
1485 // check to see if this is a function call (added 1.3.0.2)
1486 if( isa( binary->rhs->type, emit->env->t_function ) )
1487 {
1488 // take care of objects in terms of reference counting
1489 doRef = TRUE;
1490 }
1491
1492 // emit (doRef added 1.3.0.2)
1493 left = emit_engine_emit_exp( emit, binary->lhs, doRef );
1494 right = emit_engine_emit_exp( emit, binary->rhs );
1495
1496 // check
1497 if( !left || !right )
1498 return FALSE;
1499
1500 // emit the op
1501 if( !emit_engine_emit_op( emit, binary->op, binary->lhs, binary->rhs, binary ) )
1502 return FALSE;
1503
1504 return TRUE;
1505}
1506
1507
1508
1509
1510//-----------------------------------------------------------------------------
1511// name: emit_engine_emit_op()
1512// desc: emit binary operator
1513//-----------------------------------------------------------------------------
1514t_CKBOOL emit_engine_emit_op( Chuck_Emitter * emit, ae_Operator op, a_Exp lhs, a_Exp rhs, a_Exp_Binary binary )
1515{
1516 // any implicit cast happens before this
1517 Chuck_Type * t_left = lhs->cast_to ? lhs->cast_to : lhs->type;
1518 Chuck_Type * t_right = rhs->cast_to ? rhs->cast_to : rhs->type;
1519 // get the types of the left and right
1520 te_Type left = t_left->xid;
1521 te_Type right = t_right->xid;
1522 // op
1523 Chuck_Instr * instr = NULL;
1524
1525 // emit op
1526 switch( op )
1527 {
1528 // ----------------------------- num --------------------------------------
1529 case ae_op_plus:
1530 // time + dur
1531 if( ( left == te_dur && right == te_time ) ||
1532 ( left == te_time && right == te_dur ) )
1533 {
1534 emit->append( instr = new Chuck_Instr_Add_double );
1535 }
1536 // string + string
1537 else if( isa( t_left, emit->env->t_string ) && isa( t_right, emit->env->t_string ) )
1538 {
1539 // concatenate
1540 emit->append( instr = new Chuck_Instr_Add_string );
1541 instr->set_linepos( lhs->linepos );
1542 }
1543 // left: string
1544 else if( isa( t_left, emit->env->t_string ) )
1545 {
1546 // + int
1547 if( isa( t_right, emit->env->t_int ) )
1548 {
1549 emit->append( instr = new Chuck_Instr_Add_string_int );
1550 instr->set_linepos( lhs->linepos );
1551 }
1552 else if( isa( t_right, emit->env->t_float ) )
1553 {
1554 emit->append( instr = new Chuck_Instr_Add_string_float );
1555 instr->set_linepos( lhs->linepos );
1556 }
1557 else
1558 {
1559 EM_error2( lhs->linepos,
1560 "(emit): internal error: unhandled op '%s' %s '%s'",
1561 t_left->c_name(), op2str( op ), t_right->c_name() );
1562 return FALSE;
1563 }
1564 }
1565 // right: string
1566 else if( isa( t_right, emit->env->t_string ) )
1567 {
1568 // + int
1569 if( isa( t_left, emit->env->t_int ) )
1570 {
1571 emit->append( instr = new Chuck_Instr_Add_int_string );
1572 instr->set_linepos( rhs->linepos );
1573 }
1574 else if( isa( t_left, emit->env->t_float ) )
1575 {
1576 emit->append( instr = new Chuck_Instr_Add_float_string );
1577 instr->set_linepos( rhs->linepos );
1578 }
1579 else
1580 {
1581 EM_error2( lhs->linepos,
1582 "(emit): internal error: unhandled op '%s' %s '%s'",
1583 t_left->c_name(), op2str( op ), t_right->c_name() );
1584 return FALSE;
1585 }
1586 }
1587 else // other types
1588 {
1589 switch( left )
1590 {
1591 case te_int:
1592 emit->append( instr = new Chuck_Instr_Add_int );
1593 break;
1594 case te_float:
1595 case te_dur:
1596 emit->append( instr = new Chuck_Instr_Add_double );
1597 break;
1598 case te_complex:
1599 emit->append( instr = new Chuck_Instr_Add_complex );
1600 break;
1601 case te_polar:
1602 emit->append( instr = new Chuck_Instr_Add_polar );
1603 break;
1604 case te_vec3:
1605 emit->append( instr = new Chuck_Instr_Add_vec3 );
1606 break;
1607 case te_vec4:
1608 emit->append( instr = new Chuck_Instr_Add_vec4 );
1609 break;
1610
1611 default: break;
1612 }
1613 }
1614 break;
1615
1616 case ae_op_plus_chuck:
1617 // time advance
1618 if( left == te_dur && right == te_time && rhs->s_meta == ae_meta_var &&
1619 rhs->s_type == ae_exp_primary && !strcmp( "now", S_name(rhs->primary.var) ) )
1620 {
1621 // add the two
1622 emit->append( new Chuck_Instr_Add_double );
1623 // advance time (TODO: verify having two instr is OK)
1624 emit->append( instr = new Chuck_Instr_Time_Advance );
1625 instr->set_linepos( lhs->linepos );
1626 }
1627 // time + dur
1628 else if( ( left == te_dur && right == te_time ) ||
1629 ( left == te_time && right == te_dur ) )
1630 {
1631 emit->append( instr = new Chuck_Instr_Add_double_Assign );
1632 }
1633 // string + string
1634 else if( isa( t_left, emit->env->t_string ) && isa( t_right, emit->env->t_string ) )
1635 {
1636 // concatenate
1637 emit->append( instr = new Chuck_Instr_Add_string_Assign );
1638 instr->set_linepos( lhs->linepos );
1639 }
1640 // right: string
1641 else if( isa( t_right, emit->env->t_string ) )
1642 {
1643 // + int
1644 if( isa( t_left, emit->env->t_int ) )
1645 {
1646 emit->append( instr = new Chuck_Instr_Add_int_string_Assign );
1647 // null exceptions will occur from string: use rhs, not lhs
1648 instr->set_linepos( rhs->linepos );
1649 }
1650 else if( isa( t_left, emit->env->t_float ) )
1651 {
1652 emit->append( instr = new Chuck_Instr_Add_float_string_Assign );
1653 instr->set_linepos( rhs->linepos );
1654 }
1655 else
1656 {
1657 EM_error2( lhs->linepos,
1658 "(emit): internal error: unhandled op '%s' %s '%s'",
1659 t_left->c_name(), op2str( op ), t_right->c_name() );
1660 return FALSE;
1661 }
1662 }
1663 else // other types
1664 {
1665 switch( left )
1666 {
1667 case te_int:
1668 emit->append( instr = new Chuck_Instr_Add_int_Assign );
1669 break;
1670 case te_float:
1671 case te_dur:
1672 emit->append( instr = new Chuck_Instr_Add_double_Assign );
1673 break;
1674 case te_complex:
1675 emit->append( instr = new Chuck_Instr_Add_complex_Assign );
1676 break;
1677 case te_polar:
1678 emit->append( instr = new Chuck_Instr_Add_polar_Assign );
1679 break;
1680 case te_vec3:
1681 emit->append( instr = new Chuck_Instr_Add_vec3_Assign );
1682 break;
1683 case te_vec4:
1684 emit->append( instr = new Chuck_Instr_Add_vec4_Assign );
1685 break;
1686
1687 default: break;
1688 }
1689 }
1690 break;
1691
1692 case ae_op_minus:
1693 if( ( left == te_time && right == te_dur ) ) // time - dur = time
1694 emit->append( instr = new Chuck_Instr_Minus_double );
1695 else if( ( left == te_time && right == te_time ) ) // time - time = dur
1696 emit->append( instr = new Chuck_Instr_Minus_double );
1697 else // other types
1698 {
1699 switch( left )
1700 {
1701 case te_int:
1702 emit->append( instr = new Chuck_Instr_Minus_int );
1703 break;
1704 case te_float:
1705 case te_dur:
1706 emit->append( instr = new Chuck_Instr_Minus_double );
1707 break;
1708 case te_complex:
1709 emit->append( instr = new Chuck_Instr_Minus_complex );
1710 break;
1711 case te_polar:
1712 emit->append( instr = new Chuck_Instr_Minus_polar );
1713 break;
1714 case te_vec3:
1715 emit->append( instr = new Chuck_Instr_Minus_vec3 );
1716 break;
1717 case te_vec4:
1718 emit->append( instr = new Chuck_Instr_Minus_vec4 );
1719 break;
1720
1721 default: break;
1722 }
1723 }
1724 break;
1725
1726 case ae_op_minus_chuck:
1727 if( ( left == te_dur && right == te_time ) ) // time - dur = time
1728 emit->append( instr = new Chuck_Instr_Minus_double_Assign );
1729 else if( ( left == te_time && right == te_time ) ) // time - time = dur
1730 emit->append( instr = new Chuck_Instr_Minus_double_Assign );
1731 else // other types
1732 {
1733 switch( left )
1734 {
1735 case te_int:
1736 emit->append( instr = new Chuck_Instr_Minus_int_Assign );
1737 break;
1738 case te_float:
1739 case te_dur:
1740 emit->append( instr = new Chuck_Instr_Minus_double_Assign );
1741 break;
1742 case te_complex:
1743 emit->append( instr = new Chuck_Instr_Minus_complex_Assign );
1744 break;
1745 case te_polar:
1746 emit->append( instr = new Chuck_Instr_Minus_polar_Assign );
1747 break;
1748 case te_vec3:
1749 emit->append( instr = new Chuck_Instr_Minus_vec3_Assign );
1750 break;
1751 case te_vec4:
1752 emit->append( instr = new Chuck_Instr_Minus_vec4_Assign );
1753 break;
1754
1755 default: break;
1756 }
1757 }
1758 break;
1759
1760 case ae_op_times:
1761 // check
1762 if( left == te_float && right == te_vec3 )
1763 {
1764 emit->append( instr = new Chuck_Instr_float_Times_vec3 );
1765 }
1766 else if( left == te_vec3 && right == te_float )
1767 {
1768 emit->append( instr = new Chuck_Instr_vec3_Times_float );
1769 }
1770 else if( left == te_float && right == te_vec4 )
1771 {
1772 emit->append( instr = new Chuck_Instr_float_Times_vec4 );
1773 }
1774 else if( left == te_vec4 && right == te_float )
1775 {
1776 emit->append( instr = new Chuck_Instr_vec4_Times_float );
1777 }
1778 else // other cases
1779 {
1780 switch( left )
1781 {
1782 case te_int:
1783 emit->append( instr = new Chuck_Instr_Times_int );
1784 break;
1785 case te_float:
1786 case te_dur:
1787 emit->append( instr = new Chuck_Instr_Times_double );
1788 break;
1789 case te_complex:
1790 emit->append( instr = new Chuck_Instr_Times_complex );
1791 break;
1792 case te_polar:
1793 emit->append( instr = new Chuck_Instr_Times_polar );
1794 break;
1795 case te_vec3:
1796 emit->append( instr = new Chuck_Instr_XProduct_vec3 );
1797 break;
1798 case te_vec4:
1799 emit->append( instr = new Chuck_Instr_XProduct_vec4 );
1800 break;
1801
1802 default: break;
1803 }
1804 }
1805 break;
1806
1807 case ae_op_times_chuck:
1808 // check
1809 if( left == te_float && right == te_vec3 )
1810 {
1811 emit->append( instr = new Chuck_Instr_float_Times_vec3_Assign );
1812 }
1813 else if( left == te_float && right == te_vec4 )
1814 {
1815 emit->append( instr = new Chuck_Instr_float_Times_vec4_Assign );
1816 }
1817 else
1818 {
1819 switch( left )
1820 {
1821 case te_int:
1822 emit->append( instr = new Chuck_Instr_Times_int_Assign );
1823 break;
1824 case te_float:
1825 emit->append( instr = new Chuck_Instr_Times_double_Assign );
1826 break;
1827 case te_complex:
1828 emit->append( instr = new Chuck_Instr_Times_complex_Assign );
1829 break;
1830 case te_polar:
1831 emit->append( instr = new Chuck_Instr_Times_polar_Assign );
1832 break;
1833
1834 default: break;
1835 }
1836 }
1837 break;
1838
1839 case ae_op_divide:
1840 if( ( left == te_time && right == te_dur ) ) // time / dur = float
1841 emit->append( instr = new Chuck_Instr_Divide_double );
1842 else if( left == te_vec3 && right == te_float )
1843 {
1844 emit->append( instr = new Chuck_Instr_vec3_Divide_float );
1845 }
1846 else if( left == te_vec4 && right == te_float )
1847 {
1848 emit->append( instr = new Chuck_Instr_vec4_Divide_float );
1849 }
1850 else // other types
1851 {
1852 switch( left )
1853 {
1854 case te_int:
1855 emit->append( instr = new Chuck_Instr_Divide_int );
1856 instr->set_linepos( rhs->linepos );
1857 break;
1858 case te_float:
1859 case te_dur:
1860 emit->append( instr = new Chuck_Instr_Divide_double );
1861 break;
1862 case te_complex:
1863 emit->append( instr = new Chuck_Instr_Divide_complex );
1864 break;
1865 case te_polar:
1866 emit->append( instr = new Chuck_Instr_Divide_polar );
1867 break;
1868
1869 default: break;
1870 }
1871 }
1872 break;
1873
1874 case ae_op_divide_chuck:
1875 // reverse
1876 if( ( left == te_dur && right == te_time ) ) // time / dur = float
1877 emit->append( instr = new Chuck_Instr_Divide_double_Assign );
1878 else
1879 if( left == te_float && right == te_vec3 )
1880 {
1881 emit->append( instr = new Chuck_Instr_vec3_Divide_float_Assign );
1882 }
1883 else if( left == te_float && right == te_vec4 )
1884 {
1885 emit->append( instr = new Chuck_Instr_vec4_Divide_float_Assign );
1886 }
1887 else // other types
1888 {
1889 switch( left )
1890 {
1891 case te_int:
1892 emit->append( instr = new Chuck_Instr_Divide_int_Assign );
1893 instr->set_linepos( lhs->linepos );
1894 break;
1895 case te_float:
1896 emit->append( instr = new Chuck_Instr_Divide_double_Assign );
1897 break;
1898 case te_complex:
1899 emit->append( instr = new Chuck_Instr_Divide_complex_Assign );
1900 break;
1901 case te_polar:
1902 emit->append( instr = new Chuck_Instr_Divide_polar_Assign );
1903 break;
1904
1905 default: break;
1906 }
1907 }
1908 break;
1909
1910 case ae_op_s_or:
1911 switch( left )
1912 {
1913 case te_int:
1914 emit->append( instr = new Chuck_Instr_Binary_Or );
1915 break;
1916
1917 default: break;
1918 }
1919 break;
1920
1921 case ae_op_s_or_chuck:
1922 switch( left )
1923 {
1924 case te_int:
1925 emit->append( instr = new Chuck_Instr_Binary_Or_Assign );
1926 break;
1927
1928 default: break;
1929 }
1930 break;
1931
1932 case ae_op_s_and:
1933 switch( left )
1934 {
1935 case te_int:
1936 emit->append( instr = new Chuck_Instr_Binary_And );
1937 break;
1938
1939 default: break;
1940 }
1941 break;
1942
1943 case ae_op_s_and_chuck:
1944 switch( left )
1945 {
1946 case te_int:
1947 emit->append( instr = new Chuck_Instr_Binary_And_Assign );
1948 break;
1949
1950 default: break;
1951 }
1952 break;
1953
1954 case ae_op_shift_left:
1955 switch( left )
1956 {
1957 case te_int:
1958 emit->append( instr = new Chuck_Instr_Binary_Shift_Left );
1959 break;
1960
1961 case te_array:
1962 // check size (1.3.1.0: changed to getkindof)
1963 emit->append( instr = new Chuck_Instr_Array_Append( getkindof( emit->env, t_left->array_type ) ) );
1964 instr->set_linepos( lhs->linepos );
1965 break;
1966
1967 default: break;
1968 }
1969 break;
1970
1971 case ae_op_shift_left_chuck:
1972 // reverse
1973 switch( left )
1974 {
1975 case te_int:
1976 emit->append( instr = new Chuck_Instr_Binary_Shift_Left_Assign );
1977 break;
1978
1979 default: break;
1980 }
1981 break;
1982
1983 case ae_op_shift_right:
1984 switch( left )
1985 {
1986 case te_int:
1987 emit->append( instr = new Chuck_Instr_Binary_Shift_Right );
1988 break;
1989
1990 // case te_array:
1991 // emit->append( instr = new Chuck_Instr_Array_Prepend( t_left->array_type->size ) );
1992 // break;
1993
1994 default: break;
1995 }
1996 break;
1997
1998 case ae_op_shift_right_chuck:
1999 // reverse
2000 switch( left )
2001 {
2002 case te_int:
2003 emit->append( instr = new Chuck_Instr_Binary_Shift_Right_Assign );
2004 break;
2005
2006 default: break;
2007 }
2008 break;
2009
2010 case ae_op_percent:
2011 if( ( left == te_time && right == te_dur ) ) // time % dur = dur
2012 {
2013 emit->append( instr = new Chuck_Instr_Mod_double );
2014 }
2015 else // other types
2016 {
2017 switch( left )
2018 {
2019 case te_int:
2020 emit->append( instr = new Chuck_Instr_Mod_int );
2021 break;
2022 case te_float:
2023 case te_dur:
2024 emit->append( instr = new Chuck_Instr_Mod_double );
2025 break;
2026
2027 default: break;
2028 }
2029 }
2030 break;
2031
2032 case ae_op_percent_chuck:
2033 // reverse
2034 if( ( left == te_dur && right == te_time ) ) // time % dur = dur
2035 {
2036 emit->append( instr = new Chuck_Instr_Mod_double_Assign );
2037 }
2038 else // other types
2039 {
2040 switch( left )
2041 {
2042 case te_int:
2043 emit->append( instr = new Chuck_Instr_Mod_int_Assign );
2044 break;
2045 case te_float:
2046 case te_dur:
2047 emit->append( instr = new Chuck_Instr_Mod_double_Assign );
2048 break;
2049
2050 default: break;
2051 }
2052 }
2053 break;
2054
2055 case ae_op_s_xor:
2056 switch( left )
2057 {
2058 case te_int:
2059 emit->append( instr = new Chuck_Instr_Binary_Xor );
2060 break;
2061 default: break;
2062 }
2063 break;
2064
2065 case ae_op_s_xor_chuck:
2066 switch( left )
2067 {
2068 case te_int:
2069 emit->append( instr = new Chuck_Instr_Binary_Xor_Assign );
2070 break;
2071 default: break;
2072 }
2073 break;
2074
2075 // ----------------------------- chuck -------------------------------------
2076 case ae_op_chuck:
2077 {
2078 a_Exp cl = lhs, cr = rhs;
2079
2080 if( !emit_engine_emit_op_chuck( emit, cl, cr, binary ) )
2081 return FALSE;
2082
2083 return TRUE;
2084 }
2085
2086 case ae_op_unchuck:
2087 {
2088 a_Exp cl = lhs, cr = rhs;
2089
2090 // TODO: cross chuck
2091 assert( cl->next == NULL && cr->next == NULL );
2092 while( cr )
2093 {
2094 cl = lhs;
2095 while( cl )
2096 {
2097 if( !emit_engine_emit_op_unchuck( emit, cl, cr ) )
2098 return FALSE;
2099 cl = cl->next;
2100 }
2101
2102 cr = cr->next;
2103 }
2104
2105 return TRUE;
2106 }
2107
2108 case ae_op_upchuck:
2109 {
2110 a_Exp cl = lhs, cr = rhs;
2111
2112 // TODO: cross chuck
2113 assert( cl->next == NULL && cr->next == NULL );
2114 while( cr )
2115 {
2116 cl = lhs;
2117 while( cl )
2118 {
2119 if( !emit_engine_emit_op_upchuck( emit, cl, cr ) )
2120 return FALSE;
2121 cl = cl->next;
2122 }
2123
2124 cr = cr->next;
2125 }
2126
2127 return TRUE;
2128 }
2129
2130 case ae_op_at_chuck:
2131 {
2132 a_Exp cl = lhs, cr = rhs;
2133
2134 // TODO: cross chuck
2135 assert( cl->next == NULL && cr->next == NULL );
2136 while( cr )
2137 {
2138 cl = lhs;
2139 while( cl )
2140 {
2141 if( !emit_engine_emit_op_at_chuck( emit, cl, cr ) )
2142 return FALSE;
2143 cl = cl->next;
2144 }
2145
2146 cr = cr->next;
2147 }
2148
2149 return TRUE;
2150 }
2151
2152 case ae_op_s_chuck:
2153 break;
2154
2155 // -------------------------------- bool -----------------------------------
2156 case ae_op_eq:
2157 if( isa( t_left, emit->env->t_string ) && isa( t_right, emit->env->t_string )
2158 && !isa( t_left, emit->env->t_null ) && !isa( t_right, emit->env->t_null ) ) // !null
2159 {
2160 emit->append( instr = new Chuck_Instr_Op_string( op ) );
2161 instr->set_linepos( lhs->linepos );
2162 }
2163 else if( isa( t_left, emit->env->t_object ) && isa( t_right, emit->env->t_object ) )
2164 emit->append( instr = new Chuck_Instr_Eq_int );
2165 else
2166 {
2167 switch( left )
2168 {
2169 case te_int:
2170 emit->append( instr = new Chuck_Instr_Eq_int );
2171 break;
2172 case te_float:
2173 case te_dur:
2174 case te_time:
2175 emit->append( instr = new Chuck_Instr_Eq_double );
2176 break;
2177 case te_complex:
2178 case te_polar:
2179 emit->append( instr = new Chuck_Instr_Eq_complex );
2180 break;
2181 case te_vec3:
2182 emit->append( instr = new Chuck_Instr_Eq_vec3 );
2183 break;
2184 case te_vec4:
2185 emit->append( instr = new Chuck_Instr_Eq_vec4 );
2186 break;
2187
2188 default: break;
2189 }
2190 }
2191 break;
2192
2193 case ae_op_neq:
2194 if( isa( t_left, emit->env->t_string ) && isa( t_right, emit->env->t_string )
2195 && !isa( t_left, emit->env->t_null ) && !isa( t_right, emit->env->t_null ) ) // !null
2196 // added 1.3.2.0 (spencer)
2197 {
2198 emit->append( instr = new Chuck_Instr_Op_string( op ) );
2199 instr->set_linepos( lhs->linepos );
2200 }
2201 else if( isa( t_left, emit->env->t_object ) && isa( t_right, emit->env->t_object ) )
2202 emit->append( instr = new Chuck_Instr_Neq_int );
2203 else
2204 {
2205 switch( left )
2206 {
2207 case te_int:
2208 emit->append( instr = new Chuck_Instr_Neq_int );
2209 break;
2210 case te_float:
2211 case te_dur:
2212 case te_time:
2213 emit->append( instr = new Chuck_Instr_Neq_double );
2214 break;
2215 case te_complex:
2216 case te_polar:
2217 emit->append( instr = new Chuck_Instr_Neq_complex );
2218 break;
2219 case te_vec3:
2220 emit->append( instr = new Chuck_Instr_Neq_vec3 );
2221 break;
2222 case te_vec4:
2223 emit->append( instr = new Chuck_Instr_Neq_vec4 );
2224 break;
2225
2226 default: break;
2227 }
2228 }
2229 break;
2230
2231 case ae_op_lt:
2232 switch( left )
2233 {
2234 case te_int:
2235 emit->append( instr = new Chuck_Instr_Lt_int );
2236 break;
2237 case te_float:
2238 case te_dur:
2239 case te_time:
2240 emit->append( instr = new Chuck_Instr_Lt_double );
2241 break;
2242
2243 default:
2244 if( isa( t_left, emit->env->t_string ) && isa( t_right, emit->env->t_string ) )
2245 {
2246 emit->append( instr = new Chuck_Instr_Op_string( op ) );
2247 instr->set_linepos( lhs->linepos );
2248 }
2249 break;
2250 }
2251 break;
2252
2253 case ae_op_le:
2254 switch( left )
2255 {
2256 case te_int:
2257 emit->append( instr = new Chuck_Instr_Le_int );
2258 break;
2259 case te_float:
2260 case te_dur:
2261 case te_time:
2262 emit->append( instr = new Chuck_Instr_Le_double );
2263 break;
2264
2265 default:
2266 if( isa( t_left, emit->env->t_string ) && isa( t_right, emit->env->t_string ) )
2267 {
2268 emit->append( instr = new Chuck_Instr_Op_string( op ) );
2269 instr->set_linepos( lhs->linepos );
2270 }
2271 else if( isa( t_left, emit->env->t_io ) )
2272 {
2273 // output
2274 if( isa( t_right, emit->env->t_int ) )
2275 {
2276 emit->append( instr = new Chuck_Instr_IO_out_int );
2277 instr->set_linepos( rhs->linepos );
2278 }
2279 else if( isa( t_right, emit->env->t_float ) )
2280 {
2281 emit->append( instr = new Chuck_Instr_IO_out_float );
2282 instr->set_linepos( rhs->linepos );
2283 }
2284 else if( isa( t_right, emit->env->t_string ) )
2285 {
2286 emit->append( instr = new Chuck_Instr_IO_out_string );
2287 instr->set_linepos( rhs->linepos );
2288 }
2289 }
2290 break;
2291 }
2292 break;
2293
2294 case ae_op_gt:
2295 switch( left )
2296 {
2297 case te_int:
2298 emit->append( instr = new Chuck_Instr_Gt_int );
2299 break;
2300 case te_float:
2301 case te_dur:
2302 case te_time:
2303 emit->append( instr = new Chuck_Instr_Gt_double );
2304 break;
2305
2306 default:
2307 if( isa( t_left, emit->env->t_string ) && isa( t_right, emit->env->t_string ) )
2308 {
2309 emit->append( instr = new Chuck_Instr_Op_string( op ) );
2310 instr->set_linepos( lhs->linepos );
2311 }
2312 break;
2313 }
2314 break;
2315
2316 case ae_op_ge:
2317 switch( left )
2318 {
2319 case te_int:
2320 emit->append( instr = new Chuck_Instr_Ge_int );
2321 break;
2322 case te_float:
2323 case te_dur:
2324 case te_time:
2325 emit->append( instr = new Chuck_Instr_Ge_double );
2326 break;
2327
2328 default:
2329 if( isa( t_left, emit->env->t_string ) && isa( t_right, emit->env->t_string ) )
2330 {
2331 emit->append( instr = new Chuck_Instr_Op_string( op ) );
2332 instr->set_linepos( lhs->linepos );
2333 }
2334 break;
2335 }
2336 break;
2337
2338 case ae_op_and:
2339 switch( left )
2340 {
2341 case te_int:
2342 emit->append( instr = new Chuck_Instr_And );
2343 break;
2344
2345 default: break;
2346 }
2347 break;
2348
2349 case ae_op_or:
2350 switch( left )
2351 {
2352 case te_int:
2353 emit->append( instr = new Chuck_Instr_Or );
2354 break;
2355
2356 default: break;
2357 }
2358 break;
2359
2360 //------------------------------- IO ----------------------------------
2361 case ae_op_arrow_left:
2362 switch( right )
2363 {
2364 case te_int:
2365 emit->append( instr = new Chuck_Instr_IO_out_int );
2366 instr->set_linepos( rhs->linepos );
2367 break;
2368 case te_float:
2369 emit->append( instr = new Chuck_Instr_IO_out_float );
2370 instr->set_linepos( rhs->linepos );
2371 break;
2372 default:
2373 if( isa( t_right, emit->env->t_string ) )
2374 {
2375 emit->append( instr = new Chuck_Instr_IO_out_string );
2376 instr->set_linepos( rhs->linepos );
2377 }
2378 break;
2379 }
2380 break;
2381
2382 case ae_op_arrow_right:
2383 switch( right )
2384 {
2385 case te_int:
2386 emit->append( instr = new Chuck_Instr_IO_in_int );
2387 instr->set_linepos( rhs->linepos );
2388 break;
2389 case te_float:
2390 emit->append( instr = new Chuck_Instr_IO_in_float );
2391 instr->set_linepos( rhs->linepos );
2392 break;
2393 default:
2394 if( isa( t_right, emit->env->t_string ) )
2395 {
2396 emit->append( instr = new Chuck_Instr_IO_in_string );
2397 instr->set_linepos( rhs->linepos );
2398 }
2399 break;
2400 }
2401 break;
2402
2403 //---------------------------- (error) --------------------------------
2404 default:
2405 EM_error2( lhs->linepos,
2406 "(emit): internal error: unhandled op '%s' %s '%s'",
2407 t_left->c_name(), op2str( op ), t_right->c_name() );
2408 return FALSE;
2409 }
2410
2411 // make sure emit
2412 if( !instr )
2413 {
2414 EM_error2( lhs->linepos,
2415 "(emit): internal error: unhandled op '%s' %s '%s'",
2416 t_left->c_name(), op2str( op ), t_right->c_name() );
2417 return FALSE;
2418 }
2419
2420 return TRUE;
2421}
2422
2423
2424
2425
2426//-----------------------------------------------------------------------------
2427// name: emit_engine_emit_op_chuck()
2428// desc: ...
2429//-----------------------------------------------------------------------------
2430t_CKBOOL emit_engine_emit_op_chuck( Chuck_Emitter * emit, a_Exp lhs, a_Exp rhs, a_Exp_Binary binary )
2431{
2432 // any implicit cast happens before this
2433 Chuck_Type * left = lhs->cast_to ? lhs->cast_to : lhs->type;
2434 Chuck_Type * right = rhs->cast_to ? rhs->cast_to : rhs->type;
2435
2436 // the pointer
2437 Chuck_Instr * instr = NULL;
2438
2439 // ugen => ugen
2440 if( isa( left, emit->env->t_ugen ) && isa( right, emit->env->t_ugen ) )
2441 {
2442 // link, flag as NOT unchuck
2443 emit->append( instr = new Chuck_Instr_UGen_Link( FALSE ) );
2444 instr->set_linepos( lhs->linepos );
2445 // done
2446 return TRUE;
2447 }
2448
2449 // ugen[] => ugen[] (or permutation)
2450 if( ( isa( left, emit->env->t_ugen ) || ( isa( left, emit->env->t_array ) && isa( left->array_type, emit->env->t_ugen ) ) ) &&
2451 ( isa( right, emit->env->t_ugen ) || ( isa( right, emit->env->t_array ) && isa( right->array_type, emit->env->t_ugen ) ) ) )
2452 {
2453 // link, flag as NOT unchuck
2454 emit->append( instr = new Chuck_Instr_UGen_Array_Link( isa( left, emit->env->t_array ), isa( right, emit->env->t_array ) ) );
2455 instr->set_linepos( lhs->linepos );
2456 // done
2457 return TRUE;
2458 }
2459
2460 // time advance
2461 if( isa( left, emit->env->t_dur ) && isa( right, emit->env->t_time ) && rhs->s_meta == ae_meta_var )
2462 {
2463 // add the two
2464 emit->append( new Chuck_Instr_Add_double );
2465
2466 // see if rhs is 'now'
2467 if( rhs->s_type == ae_exp_primary && !strcmp( "now", S_name(rhs->primary.var) ) )
2468 {
2469 // advance time
2470 emit->append( instr = new Chuck_Instr_Time_Advance );
2471 instr->set_linepos( lhs->linepos );
2472 }
2473
2474 return TRUE;
2475 }
2476
2477 // time advance
2478 if( isa( left, emit->env->t_event ) && isa( right, emit->env->t_time ) && rhs->s_meta == ae_meta_var &&
2479 rhs->s_type == ae_exp_primary && !strcmp( "now", S_name(rhs->primary.var) ) )
2480 {
2481 // pop now
2482 emit->append( new Chuck_Instr_Reg_Pop_Word2 );
2483 emit->append( instr = new Chuck_Instr_Event_Wait );
2484 instr->set_linepos( lhs->linepos );
2485
2486 return TRUE;
2487 }
2488
2489 // input
2490 if( isa( left, emit->env->t_io ) )
2491 {
2492 if( isa( right, emit->env->t_int ) )
2493 {
2494 assert( rhs->s_meta == ae_meta_var );
2495 emit->append( instr = new Chuck_Instr_IO_in_int );
2496 instr->set_linepos( rhs->linepos );
2497 return TRUE;
2498 }
2499 else if( isa( right, emit->env->t_float ) )
2500 {
2501 assert( rhs->s_meta == ae_meta_var );
2502 emit->append( instr = new Chuck_Instr_IO_in_float );
2503 instr->set_linepos( rhs->linepos );
2504 return TRUE;
2505 }
2506 else if( isa( right, emit->env->t_string ) )
2507 {
2508 assert( rhs->s_meta == ae_meta_var );
2509 emit->append( instr = new Chuck_Instr_IO_in_string );
2510 instr->set_linepos( rhs->linepos );
2511 return TRUE;
2512 }
2513 }
2514
2515 // func call
2516 if( isa( right, emit->env->t_function ) )
2517 {
2518 assert( binary->ck_func != NULL );
2519
2520 // emit
2521 return emit_engine_emit_exp_func_call( emit, binary->ck_func, binary->self->type, binary->linepos );
2522 }
2523
2524 // assignment or something else
2525 if( isa( left, right ) )
2526 {
2527 // basic types?
2528 if( type_engine_check_primitive( emit->env, left ) || isa( left, emit->env->t_string ) )
2529 {
2530 // use at assign
2531 return emit_engine_emit_op_at_chuck( emit, lhs, rhs );
2532 }
2533 }
2534
2535 // TODO: check overloading of =>
2536 // TODO: deal with const
2537
2538 // no match
2539 EM_error2( lhs->linepos,
2540 "(emit): internal error: unhandled '=>' on types '%s' and '%s'...",
2541 left->c_name(), right->c_name() );
2542
2543 return FALSE;
2544}
2545
2546
2547
2548
2549//-----------------------------------------------------------------------------
2550// name: emit_engine_emit_op_unchuck()
2551// desc: ...
2552//-----------------------------------------------------------------------------
2553t_CKBOOL emit_engine_emit_op_unchuck( Chuck_Emitter * emit, a_Exp lhs, a_Exp rhs )
2554{
2555 // any implicit cast happens before this
2556 Chuck_Type * left = lhs->cast_to ? lhs->cast_to : lhs->type;
2557 Chuck_Type * right = rhs->cast_to ? rhs->cast_to : rhs->type;
2558
2559 // if ugen
2560 if( isa( left, emit->env->t_ugen ) && isa( right, emit->env->t_ugen ) )
2561 {
2562 // no connect
2563 emit->append( new Chuck_Instr_UGen_UnLink );
2564 }
2565 else
2566 {
2567 EM_error2( lhs->linepos,
2568 "(emit): internal error: unhandled '=<' on types '%s' and '%s'",
2569 left->c_name(), right->c_name() );
2570 return FALSE;
2571 }
2572
2573 return TRUE;
2574}
2575
2576
2577
2578
2579//-----------------------------------------------------------------------------
2580// name: emit_engine_emit_op_upchuck()
2581// desc: ...
2582//-----------------------------------------------------------------------------
2583t_CKBOOL emit_engine_emit_op_upchuck( Chuck_Emitter * emit, a_Exp lhs, a_Exp rhs )
2584{
2585 // any implicit cast happens before this
2586 Chuck_Type * left = lhs->cast_to ? lhs->cast_to : lhs->type;
2587 Chuck_Type * right = rhs->cast_to ? rhs->cast_to : rhs->type;
2588
2589 // if ugen
2590 if( isa( left, emit->env->t_uana ) && isa( right, emit->env->t_uana ) )
2591 {
2592 // connect; flag it as unchuck
2593 Chuck_Instr * instr = NULL;
2594 emit->append( instr = new Chuck_Instr_UGen_Link( TRUE ) );
2595 instr->set_linepos( lhs->linepos );
2596 }
2597 else
2598 {
2599 EM_error2( lhs->linepos,
2600 "(emit): internal error: unhandled '=^' on types '%s' and '%s'",
2601 left->c_name(), right->c_name() );
2602 return FALSE;
2603 }
2604
2605 return TRUE;
2606}
2607
2608
2609
2610
2611//-----------------------------------------------------------------------------
2612// name: emit_engine_emit_op_at_chuck()
2613// desc: ...
2614//-----------------------------------------------------------------------------
2615t_CKBOOL emit_engine_emit_op_at_chuck( Chuck_Emitter * emit, a_Exp lhs, a_Exp rhs )
2616{
2617 // any implicit cast happens before this
2618 Chuck_Type * left = lhs->cast_to ? lhs->cast_to : lhs->type;
2619 Chuck_Type * right = rhs->cast_to ? rhs->cast_to : rhs->type;
2620
2621 // assignment or something else
2622 if( isa( left, right ) )
2623 {
2624 // basic types?
2625 if( type_engine_check_primitive( emit->env, left ) || isa( left, emit->env->t_string ) )
2626 {
2627 // assigment?
2628 if( rhs->s_meta != ae_meta_var )
2629 {
2630 EM_error2( lhs->linepos,
2631 "(emit): internal error: assignment to non-variable..." );
2632 return FALSE;
2633 }
2634
2635 // see if rhs is 'now' - time => now
2636 if( rhs->s_type == ae_exp_primary && !strcmp( "now", S_name(rhs->primary.var) ) )
2637 {
2638 // pop the now addr
2639 emit->append( new Chuck_Instr_Reg_Pop_Word2 );
2640 // advance time
2641 Chuck_Instr * instr = NULL;
2642 emit->append( instr = new Chuck_Instr_Time_Advance );
2643 instr->set_linepos( lhs->linepos );
2644 }
2645 else if( isa( left, emit->env->t_string ) ) // string
2646 {
2647 // assign string
2648 emit->append( new Chuck_Instr_Assign_String );
2649 }
2650 else
2651 {
2652 // assign primitive
2653 // added 1.3.1.0: iskindofint -- since on some 64-bit systems, sz_INT == sz_FLOAT
2654 if( right->size == sz_INT && iskindofint(emit->env, right) ) // ISSUE: 64-bit (fixed 1.3.1.0)
2655 emit->append( new Chuck_Instr_Assign_Primitive );
2656 else if( right->size == sz_FLOAT ) // ISSUE: 64-bit (fixed 1.3.1.0)
2657 emit->append( new Chuck_Instr_Assign_Primitive2 );
2658 else if( right->size == sz_COMPLEX ) // ISSUE: 64-bit (fixed 1.3.1.0)
2659 emit->append( new Chuck_Instr_Assign_Primitive4 );
2660 else if( right->size == sz_VEC3 ) // ge: added 1.3.5.3
2661 emit->append( new Chuck_Instr_Assign_PrimitiveVec3 );
2662 else if( right->size == sz_VEC4 ) // ge: added 1.3.5.3
2663 emit->append( new Chuck_Instr_Assign_PrimitiveVec4 );
2664 else
2665 {
2666 EM_error2( rhs->linepos,
2667 "(emit): internal error: assignment to type of size %i...",
2668 right->size );
2669 }
2670 }
2671
2672 return TRUE;
2673 }
2674 else // objects
2675 {
2676 // assign object
2677 emit->append( new Chuck_Instr_Assign_Object );
2678
2679 return TRUE;
2680 }
2681 }
2682
2683 // TODO: check overloading of =>
2684 // TODO: deal with const
2685
2686 // no match
2687 EM_error2( lhs->linepos,
2688 "(emit): internal error: unhandled '@=>' on types '%s' and '%s'...",
2689 left->c_name(), right->c_name() );
2690
2691 return FALSE;
2692}
2693
2694
2695
2696
2697//-----------------------------------------------------------------------------
2698// name: emit_engine_emit_exp_unary()
2699// desc: ...
2700//-----------------------------------------------------------------------------
2701t_CKBOOL emit_engine_emit_exp_unary( Chuck_Emitter * emit, a_Exp_Unary unary )
2702{
2703 if( unary->op != ae_op_spork && !emit_engine_emit_exp( emit, unary->exp ) )
2704 return FALSE;
2705
2706 // get type
2707 Chuck_Type * t = unary->self->type;
2708 assert( t != NULL );
2709
2710 // emit the operator
2711 switch( unary->op )
2712 {
2713 case ae_op_plusplus:
2714 // make sure assignment is legal
2715 if( unary->self->s_meta != ae_meta_var ) // TODO: const
2716 {
2717 EM_error2( unary->self->linepos,
2718 "(emit): target for '++' not mutable..." );
2719 return FALSE;
2720 }
2721
2722 // increment
2723 if( equals( unary->exp->type, emit->env->t_int ) )
2724 emit->append( new Chuck_Instr_PreInc_int );
2725 else
2726 {
2727 EM_error2( unary->linepos,
2728 "(emit): internal error: unhandled type '%s' for pre '++'' operator",
2729 unary->exp->type->c_name() );
2730 return FALSE;
2731 }
2732 break;
2733
2734 case ae_op_minusminus:
2735 // make sure assignment is legal
2736 if( unary->self->s_meta != ae_meta_var ) // TODO: const
2737 {
2738 EM_error2( unary->self->linepos,
2739 "(emit): target for '--' not mutable..." );
2740 return FALSE;
2741 }
2742
2743 // decrement
2744 if( equals( unary->exp->type, emit->env->t_int ) )
2745 emit->append( new Chuck_Instr_PreDec_int );
2746 else
2747 {
2748 EM_error2( unary->linepos,
2749 "(emit): internal error: unhandled type '%s' for pre '--' operator",
2750 unary->exp->type->c_name() );
2751 return FALSE;
2752 }
2753 break;
2754
2755 case ae_op_tilda:
2756 // complement
2757 if( equals( unary->exp->type, emit->env->t_int ) )
2758 emit->append( new Chuck_Instr_Complement_int );
2759 else
2760 {
2761 EM_error2( unary->linepos,
2762 "(emit): internal error: unhandled type '%s' for '~' operator",
2763 unary->exp->type->c_name() );
2764 return FALSE;
2765 }
2766 break;
2767
2768 case ae_op_exclamation:
2769 // !
2770 if( equals( unary->exp->type, emit->env->t_int ) )
2771 emit->append( new Chuck_Instr_Not_int );
2772 else
2773 {
2774 EM_error2( unary->linepos,
2775 "(emit): internal error: unhandled type '%s' for '!' operator",
2776 unary->exp->type->c_name() );
2777 return FALSE;
2778 }
2779 break;
2780
2781 case ae_op_minus:
2782 // negate
2783 if( equals( unary->exp->type, emit->env->t_int ) )
2784 emit->append( new Chuck_Instr_Negate_int );
2785 else if( equals( unary->exp->type, emit->env->t_float ) )
2786 emit->append( new Chuck_Instr_Negate_double );
2787 else
2788 {
2789 EM_error2( unary->linepos,
2790 "(emit): internal error: unhandled type '%s' for unary '-' operator",
2791 unary->exp->type->c_name() );
2792 return FALSE;
2793 }
2794 break;
2795
2796 case ae_op_spork:
2797 // spork ~ func()
2798 if( unary->exp && unary->exp->s_type == ae_exp_func_call )
2799 {
2800 if( !emit_engine_emit_spork( emit, &unary->exp->func_call ) )
2801 return FALSE;
2802 }
2803 // spork ~ { ... }
2804 // else if( unary->code )
2805 // {
2806 // if( !emit_engine_emit_spork( emit, unary->code ) )
2807 // return FALSE;
2808 // }
2809 else
2810 {
2811 EM_error2( unary->linepos,
2812 "(emit): internal error: sporking non-function call..." );
2813 return FALSE;
2814 }
2815 break;
2816
2817 case ae_op_new:
2818
2819 // if this is an object
2820 if( isobj( emit->env, t ) )
2821 {
2822 // instantiate object, including array
2823 if( !emit_engine_instantiate_object( emit, t, unary->array, unary->type->ref ) )
2824 return FALSE;
2825 }
2826 break;
2827
2828 default:
2829 EM_error2( unary->linepos,
2830 "(emit): internal error: unhandled unary op '%s",
2831 op2str( unary->op ) );
2832 return FALSE;
2833 }
2834
2835 return TRUE;
2836}
2837
2838
2839
2840
2841//-----------------------------------------------------------------------------
2842// name: emit_engine_emit_exp_primary()
2843// desc: ...
2844//-----------------------------------------------------------------------------
2845t_CKBOOL emit_engine_emit_exp_primary( Chuck_Emitter * emit, a_Exp_Primary exp )
2846{
2847 t_CKUINT temp;
2848 t_CKDUR dur;
2849 Chuck_String * str = NULL;
2850
2851 // find out exp
2852 switch( exp->s_type )
2853 {
2854 case ae_primary_var:
2855 if( exp->var == insert_symbol( "now" ) )
2856 {
2857 emit->append( new Chuck_Instr_Reg_Push_Now );
2858 }
2859 else if( exp->var == insert_symbol( "this" ) )
2860 {
2861 // TODO: verify this is in the right scope
2862 emit->append( new Chuck_Instr_Reg_Push_This );
2863 }
2864 else if( exp->var == insert_symbol( "me" ) )
2865 {
2866 emit->append( new Chuck_Instr_Reg_Push_Me );
2867 }
2868 else if( exp->var == insert_symbol( "true" ) )
2869 {
2870 emit->append( new Chuck_Instr_Reg_Push_Imm( 1 ) );
2871 }
2872 else if( exp->var == insert_symbol( "false" ) )
2873 {
2874 emit->append( new Chuck_Instr_Reg_Push_Imm( 0 ) );
2875 }
2876 else if( exp->var == insert_symbol("maybe") )
2877 {
2878 emit->append( new Chuck_Instr_Reg_Push_Maybe() );
2879 }
2880 else if( exp->var == insert_symbol("null") ||
2881 exp->var == insert_symbol("NULL") )
2882 {
2883 emit->append( new Chuck_Instr_Reg_Push_Imm( 0 ) );
2884 }
2885 else if( exp->var == insert_symbol( "pi" ) )
2886 {
2887 double pi = 3.14159265358979323846;
2888 emit->append( new Chuck_Instr_Reg_Push_Imm2( pi ) );
2889 }
2890 else if( exp->var == insert_symbol( "dac" ) )
2891 {
2892 emit->append( new Chuck_Instr_DAC );
2893 }
2894 else if( exp->var == insert_symbol( "adc" ) )
2895 {
2896 emit->append( new Chuck_Instr_ADC );
2897 }
2898 else if( exp->var == insert_symbol( "bunghole" ) )
2899 {
2900 emit->append( new Chuck_Instr_Bunghole );
2901 }
2902 else if( exp->var == insert_symbol( "blackhole" ) )
2903 {
2904 emit->append( new Chuck_Instr_Bunghole );
2905 }
2906 else if( exp->var == insert_symbol( "chout" ) )
2907 {
2908 emit->append( new Chuck_Instr_Chout );
2909 }
2910 else if( exp->var == insert_symbol( "cherr" ) )
2911 {
2912 emit->append( new Chuck_Instr_Cherr );
2913 }
2914 else if( emit->find_dur( S_name(exp->var), &dur ) )
2915 {
2916 emit->append( new Chuck_Instr_Reg_Push_Imm2( dur ) );
2917 }
2918 else
2919 {
2920 // emit the symbol
2921 return emit_engine_emit_symbol(
2922 emit, exp->var, exp->value, exp->self->emit_var, exp->linepos );
2923 }
2924 break;
2925
2926 case ae_primary_num:
2927 memcpy( &temp, &exp->num, sizeof(temp) );
2928 emit->append( new Chuck_Instr_Reg_Push_Imm( temp ) );
2929 break;
2930
2931 case ae_primary_float:
2932 emit->append( new Chuck_Instr_Reg_Push_Imm2( exp->fnum ) );
2933 break;
2934
2935 case ae_primary_str:
2936 // TODO: fix this
2937 str = new Chuck_String();
2938 if( !str || !initialize_object( str, emit->env->t_string ) )
2939 {
2940 // error (TODO: why is this a SAFE_RELEASE and not SAFE_DELETE?)
2941 SAFE_RELEASE( str );
2942 // error out
2943 CK_FPRINTF_STDERR(
2944 "[chuck](emitter): OutOfMemory: while allocating string literal '%s'\n", exp->str );
2945 return FALSE;
2946 }
2947 str->set( exp->str );
2948 temp = (t_CKUINT)str;
2949 emit->append( new Chuck_Instr_Reg_Push_Imm( temp ) );
2950 // add reference for string literal (added 1.3.0.2)
2951 str->add_ref();
2952 break;
2953
2954 case ae_primary_char:
2955 emit->append( new Chuck_Instr_Reg_Push_Imm( str2char(exp->chr, exp->linepos ) ) );
2956 break;
2957
2958 case ae_primary_array:
2959 if( !emit_engine_emit_array_lit( emit, exp->array ) )
2960 return FALSE;
2961 break;
2962
2963 case ae_primary_complex:
2964 if( !emit_engine_emit_complex_lit( emit, exp->complex ) )
2965 return FALSE;
2966 break;
2967
2968 case ae_primary_polar:
2969 if( !emit_engine_emit_polar_lit( emit, exp->polar ) )
2970 return FALSE;
2971 break;
2972
2973 case ae_primary_vec:
2974 if( !emit_engine_emit_vec_lit( emit, exp->vec ) )
2975 return FALSE;
2976 break;
2977
2978 case ae_primary_exp:
2979 if( !emit_engine_emit_exp( emit, exp->exp ) )
2980 return FALSE;
2981 break;
2982
2983 case ae_primary_hack:
2984 {
2985 a_Exp e = exp->exp;
2986 // emit the expression
2987 if( !emit_engine_emit_exp( emit, e ) )
2988 return FALSE;
2989 std::vector<Chuck_Type *> types;
2990
2991 while( e != NULL )
2992 {
2993 types.push_back( e->type );
2994 e = e->next;
2995 }
2996
2997 // emit hack
2998 emit->append( new Chuck_Instr_Gack( types ) );
2999
3000 break;
3001 }
3002
3003 // ge (april 2012): nil is void, so nothing to emit; TODO: check it (added 1.3.0.0)
3004 case ae_primary_nil:
3005 break;
3006 }
3007
3008 return TRUE;
3009}
3010
3011
3012
3013
3014//-----------------------------------------------------------------------------
3015// name: emit_engine_emit_array_lit()
3016// desc: ...
3017//-----------------------------------------------------------------------------
3018t_CKBOOL emit_engine_emit_array_lit( Chuck_Emitter * emit, a_Array_Sub array )
3019{
3020 // go through and emit the expressions
3021 if( !emit_engine_emit_exp( emit, array->exp_list ) )
3022 return FALSE;
3023
3024 // count the number
3025 a_Exp e = array->exp_list;
3026 t_CKUINT count = 0;
3027 // loop over
3028 while( e ) { count++; e = e->next; }
3029
3030 // the type
3031 e = array->exp_list;
3032 Chuck_Type * type = e->cast_to ? e->cast_to : e->type;
3033
3034 // construct array dynamically
3035 Chuck_Instr * instr = NULL;
3036 emit->append( instr = new Chuck_Instr_Array_Init( emit->env, type, count ) );
3037 instr->set_linepos( array->linepos );
3038
3039 return TRUE;
3040}
3041
3042
3043
3044
3045//-----------------------------------------------------------------------------
3046// name: emit_engine_emit_complex_lit()
3047// desc: ...
3048//-----------------------------------------------------------------------------
3049t_CKBOOL emit_engine_emit_complex_lit( Chuck_Emitter * emit, a_Complex val )
3050{
3051 // go through and emit the real and imaginary
3052 if( !emit_engine_emit_exp( emit, val->re ) )
3053 return FALSE;
3054
3055 // imaginary (not needed since linked after real
3056 // if( !emit_engine_emit_exp( emit, val->im ) )
3057 // return FALSE;
3058
3059 return TRUE;
3060}
3061
3062
3063
3064
3065//-----------------------------------------------------------------------------
3066// name: emit_engine_emit_polar_lit()
3067// desc: ...
3068//-----------------------------------------------------------------------------
3069t_CKBOOL emit_engine_emit_polar_lit( Chuck_Emitter * emit, a_Polar val )
3070{
3071 // go through and emit the mod and phase
3072 if( !emit_engine_emit_exp( emit, val->mod ) )
3073 return FALSE;
3074
3075 // phase (not needed since linked after mod)
3076 // if( !emit_engine_emit_exp( emit, val->phase ) )
3077 // return FALSE;
3078
3079 return TRUE;
3080}
3081
3082
3083
3084
3085//-----------------------------------------------------------------------------
3086// name: emit_engine_emit_vec_lit()
3087// desc: ...
3088//-----------------------------------------------------------------------------
3089t_CKBOOL emit_engine_emit_vec_lit( Chuck_Emitter * emit, a_Vec val )
3090{
3091 // go through and emit the mod and phase
3092 if( !emit_engine_emit_exp( emit, val->args ) )
3093 return FALSE;
3094
3095 // zero pad if needed
3096 t_CKINT n = 3 - val->numdims;
3097 // any remaining
3098 while( n > 0 )
3099 {
3100 // emit a zero float
3101 emit->append( new Chuck_Instr_Reg_Push_Imm2( 0 ) );
3102 // decrement
3103 n--;
3104 }
3105
3106 return TRUE;
3107}
3108
3109
3110
3111
3112//-----------------------------------------------------------------------------
3113// name: emit_engine_emit_exp_cast()
3114// desc: ...
3115//-----------------------------------------------------------------------------
3116t_CKBOOL emit_engine_emit_exp_cast( Chuck_Emitter * emit, a_Exp_Cast cast )
3117{
3118 Chuck_Type * to = cast->self->type;
3119 Chuck_Type * from = cast->exp->type;
3120
3121 // emit the exp
3122 if( !emit_engine_emit_exp( emit, cast->exp ) )
3123 return FALSE;
3124
3125 // the actual work to be done
3126 return emit_engine_emit_cast( emit, to, from );
3127}
3128
3129
3130
3131
3132//-----------------------------------------------------------------------------
3133// name: emit_engine_emit_cast()
3134// desc: ...
3135//-----------------------------------------------------------------------------
3136t_CKBOOL emit_engine_emit_cast( Chuck_Emitter * emit,
3137 Chuck_Type * to, Chuck_Type * from )
3138{
3139 // if type is already the same
3140 if( equals( to, from ) )
3141 return TRUE;
3142
3143 // int to float
3144 if( equals( to, emit->env->t_int ) && equals( from, emit->env->t_float ) )
3145 emit->append( new Chuck_Instr_Cast_double2int );
3146 // float to int
3147 else if( equals( to, emit->env->t_float ) && equals( from, emit->env->t_int ) )
3148 emit->append( new Chuck_Instr_Cast_int2double );
3149 else if( equals( to, emit->env->t_complex ) && equals( from, emit->env->t_int ) )
3150 emit->append( new Chuck_Instr_Cast_int2complex );
3151 else if( equals( to, emit->env->t_polar ) && equals( from, emit->env->t_int ) )
3152 emit->append( new Chuck_Instr_Cast_int2polar );
3153 else if( equals( to, emit->env->t_complex ) && equals( from, emit->env->t_float ) )
3154 emit->append( new Chuck_Instr_Cast_double2complex );
3155 else if( equals( to, emit->env->t_polar ) && equals( from, emit->env->t_float ) )
3156 emit->append( new Chuck_Instr_Cast_double2polar );
3157 else if( equals( to, emit->env->t_polar ) && equals( from, emit->env->t_complex ) )
3158 emit->append( new Chuck_Instr_Cast_complex2polar );
3159 else if( equals( to, emit->env->t_complex ) && equals( from, emit->env->t_polar ) )
3160 emit->append( new Chuck_Instr_Cast_polar2complex );
3161 else if( equals( to, emit->env->t_vec3 ) && equals( from, emit->env->t_vec4 ) )
3162 emit->append( new Chuck_Instr_Cast_vec4tovec3 );
3163 else if( equals( to, emit->env->t_vec4 ) && equals( from, emit->env->t_vec3 ) )
3164 emit->append( new Chuck_Instr_Cast_vec3tovec4 );
3165 else if( equals( to, emit->env->t_string ) && isa( from, emit->env->t_object ) && !isa( from, emit->env->t_string ) )
3166 emit->append( new Chuck_Instr_Cast_object2string );
3167 // up cast - do nothing
3168 else if( !isa( to, from ) && !isa( from, to ) )
3169 {
3170 EM_error2( 0, "(emit): internal error: cannot cast type '%s' to '%s'",
3171 from->c_name(), to->c_name() );
3172 return FALSE;
3173 }
3174
3175 return TRUE;
3176}
3177
3178
3179
3180
3181//-----------------------------------------------------------------------------
3182// name: emit_engine_emit_exp_postfix()
3183// desc: ...
3184//-----------------------------------------------------------------------------
3185t_CKBOOL emit_engine_emit_exp_postfix( Chuck_Emitter * emit, a_Exp_Postfix postfix )
3186{
3187 // emit the exp
3188 if( !emit_engine_emit_exp( emit, postfix->exp ) )
3189 return FALSE;
3190
3191 // emit
3192 switch( postfix->op )
3193 {
3194 case ae_op_plusplus:
3195 if( equals( postfix->exp->type, emit->env->t_int ) )
3196 emit->append( new Chuck_Instr_PostInc_int );
3197 else
3198 {
3199 EM_error2( postfix->linepos,
3200 "(emit): internal error: unhandled type '%s' for post '++' operator",
3201 postfix->exp->type->c_name() );
3202 return FALSE;
3203 }
3204 break;
3205
3206 case ae_op_minusminus:
3207 if( equals( postfix->exp->type, emit->env->t_int ) )
3208 emit->append( new Chuck_Instr_PostDec_int );
3209 else
3210 {
3211 EM_error2( postfix->linepos,
3212 "(emit): internal error: unhandled type '%s' for post '--' operator",
3213 postfix->exp->type->c_name() );
3214 return FALSE;
3215 }
3216 break;
3217
3218 default:
3219 EM_error2( postfix->linepos,
3220 "(emit): internal error: unhandled postfix operator '%s'",
3221 op2str( postfix->op ) );
3222 return FALSE;
3223 }
3224
3225 return TRUE;
3226}
3227
3228
3229
3230
3231//-----------------------------------------------------------------------------
3232// name: emit_engine_emit_exp_dur()
3233// desc: ...
3234//-----------------------------------------------------------------------------
3235t_CKBOOL emit_engine_emit_exp_dur( Chuck_Emitter * emit, a_Exp_Dur dur )
3236{
3237 // emit base
3238 if( !emit_engine_emit_exp( emit, dur->base ) )
3239 return FALSE;
3240
3241 // cast
3242 if( equals( dur->base->type, emit->env->t_int ) )
3243 emit->append( new Chuck_Instr_Cast_int2double );
3244
3245 // emit unit
3246 if( !emit_engine_emit_exp( emit, dur->unit ) )
3247 return FALSE;
3248
3249 // multiply
3250 emit->append( new Chuck_Instr_Times_double );
3251
3252 return TRUE;
3253}
3254
3255
3256
3257
3258//-----------------------------------------------------------------------------
3259// name: emit_engine_emit_exp_array()
3260// desc: ...
3261//-----------------------------------------------------------------------------
3262t_CKBOOL emit_engine_emit_exp_array( Chuck_Emitter * emit, a_Exp_Array array )
3263{
3264 Chuck_Type * type = NULL, * base_type = NULL;
3265 t_CKUINT depth = 0;
3266 a_Array_Sub sub = NULL;
3267 a_Exp exp = NULL;
3268 t_CKBOOL is_var = FALSE;
3269 t_CKBOOL is_str = FALSE;
3270
3271 // get the type
3272 type = array->self->type;
3273 // get the base type
3274 base_type = array->base->type;
3275 // emit as addr?
3276 is_var = array->self->emit_var;
3277 // get the dimension
3278 depth = base_type->array_depth - type->array_depth;
3279 // make sure
3280 if( depth == 0 )
3281 {
3282 EM_error2( array->linepos,
3283 "(emit): internal error: array with 0 depth..." );
3284 return FALSE;
3285 }
3286 // get the sub
3287 sub = array->indices;
3288 if( !sub )
3289 {
3290 EM_error2( array->linepos,
3291 "(emit): internal error: NULL array sub..." );
3292 return FALSE;
3293 }
3294 // get the exp list
3295 exp = sub->exp_list;
3296 if( !exp )
3297 {
3298 EM_error2( array->linepos,
3299 "(emit): internal error: NULL array exp..." );
3300 return FALSE;
3301 }
3302
3303 // emit the base (it should be a pointer to array)
3304 if( !emit_engine_emit_exp( emit, array->base ) )
3305 return FALSE;
3306
3307 // emit the exp list
3308 if( !emit_engine_emit_exp( emit, exp ) )
3309 return FALSE;
3310
3311 // find out first element
3312 if( isa( exp->type, emit->env->t_string ) )
3313 is_str = TRUE;
3314
3315 // make sure
3316 // ISSUE: 64-bit (fixed 1.3.1.0)
3317 if( type->size != sz_INT && type->size != sz_FLOAT && type->size != sz_COMPLEX &&
3318 type->size != sz_VEC3 && type->size != sz_VEC4 )
3319 {
3320 EM_error2( array->linepos,
3321 "(emit): internal error: array with datasize of %i...", type->size );
3322 return FALSE;
3323 }
3324
3325 // check the depth
3326 if( depth == 1 )
3327 {
3328 // the pointer
3329 Chuck_Instr * instr = NULL;
3330 // emit the array access (1.3.1.0: use getkindof instead of type->size)
3331 if( is_str )
3332 emit->append( instr = new Chuck_Instr_Array_Map_Access( getkindof(emit->env, type), is_var ) );
3333 else
3334 emit->append( instr = new Chuck_Instr_Array_Access( getkindof(emit->env, type), is_var ) );
3335 instr->set_linepos( array->linepos );
3336 }
3337 else
3338 {
3339 // the pointer
3340 Chuck_Instr_Array_Access_Multi * aam = NULL;
3341 // emit the multi array access (1.3.1.0: use getkindof instead of type->size)
3342 emit->append( aam = new Chuck_Instr_Array_Access_Multi( depth, getkindof(emit->env, type), is_var ) );
3343 aam->set_linepos( array->linepos );
3344 // add type info (1.3.1.0) -- to support mixed string & int indexing (thanks Robin Haberkorn)
3345 a_Exp e = exp;
3346 while( e )
3347 {
3348 // check if string
3349 aam->indexIsAssociative().push_back( isa( exp->type, emit->env->t_string ) );
3350 // next
3351 e = e->next;
3352 }
3353 }
3354
3355 // TODO: variable?
3356
3357 return TRUE;
3358}
3359
3360
3361
3362
3363//-----------------------------------------------------------------------------
3364// name: emit_engine_emit_exp_func_call()
3365// desc: ...
3366//-----------------------------------------------------------------------------
3367t_CKBOOL emit_engine_emit_exp_func_call( Chuck_Emitter * emit,
3368 Chuck_Func * func,
3369 Chuck_Type * type,
3370 int linepos,
3371 t_CKBOOL spork )
3372{
3373 // is a member?
3374 t_CKBOOL is_member = func->is_member;
3375
3376 // if member
3377 //if( is_member )
3378 //{
3379 // // this
3380 // emit->append( new Chuck_Instr_Reg_Push_This );
3381 //}
3382
3383 // translate to code
3384 emit->append( new Chuck_Instr_Func_To_Code );
3385 // emit->append( new Chuck_Instr_Reg_Push_Imm( (t_CKUINT)func->code ) );
3386 // push the local stack depth - local variables
3387 emit->append( new Chuck_Instr_Reg_Push_Imm( emit->code->frame->curr_offset ) );
3388
3389 // TODO: member functions and static functions
3390 // call the function
3391 t_CKUINT size = type->size;
3392 t_CKUINT kind = getkindof( emit->env, type ); // added 1.3.1.0
3393
3394 // the pointer
3395 Chuck_Instr * instr = NULL;
3396 if( func->def->s_type == ae_func_builtin )
3397 {
3398 // ISSUE: 64-bit (fixed 1.3.1.0)
3399 if( size == 0 || size == sz_INT || size == sz_FLOAT || size == sz_COMPLEX ||
3400 size == sz_VEC3 || sz_VEC4 )
3401 {
3402 // is member (1.3.1.0: changed to use kind instead of size)
3403 if( is_member )
3404 emit->append( instr = new Chuck_Instr_Func_Call_Member( kind ) );
3405 else
3406 emit->append( instr = new Chuck_Instr_Func_Call_Static( kind ) );
3407 }
3408 else
3409 {
3410 EM_error2( linepos,
3411 "(emit): internal error: %i func call not handled",
3412 size );
3413 return FALSE;
3414 }
3415 }
3416 else
3417 {
3418 emit->append( instr = new Chuck_Instr_Func_Call );
3419 }
3420 instr->set_linepos(linepos);
3421
3422 return TRUE;
3423}
3424
3425
3426
3427
3428//-----------------------------------------------------------------------------
3429// name: emit_engine_emit_func_args()
3430// desc: ...
3431//-----------------------------------------------------------------------------
3432t_CKBOOL emit_engine_emit_func_args( Chuck_Emitter * emit,
3433 a_Exp_Func_Call func_call )
3434{
3435 // emit the args (TRUE for doAddRef added 1.3.0.0)
3436 if( !emit_engine_emit_exp( emit, func_call->args, TRUE ) )
3437 {
3438 EM_error2( func_call->linepos,
3439 "(emit): internal error in emitting function call arguments..." );
3440 return FALSE;
3441 }
3442
3443 return TRUE;
3444}
3445
3446
3447
3448
3449//-----------------------------------------------------------------------------
3450// name: emit_engine_emit_exp_func_call()
3451// desc: ...
3452//-----------------------------------------------------------------------------
3453t_CKBOOL emit_engine_emit_exp_func_call( Chuck_Emitter * emit,
3454 a_Exp_Func_Call func_call,
3455 t_CKBOOL spork )
3456{
3457 // note: spork situations are now taken care in exp_spork...
3458 // please look at that one before modifying this one!
3459
3460 // make sure there are args, and not sporking
3461 if( func_call->args && !spork )
3462 {
3463 if( !emit_engine_emit_func_args( emit, func_call ) )
3464 return FALSE;
3465 }
3466
3467 // emit func
3468 if( !emit_engine_emit_exp( emit, func_call->func ) )
3469 {
3470 EM_error2( func_call->linepos,
3471 "(emit): internal error in evaluating function call..." );
3472 return FALSE;
3473 }
3474
3475 // the rest
3476 return emit_engine_emit_exp_func_call( emit, func_call->ck_func, func_call->ret_type,
3477 func_call->linepos, spork );
3478}
3479
3480
3481
3482
3483//-----------------------------------------------------------------------------
3484// name: emit_engine_emit_dot_member_special()
3485// desc: emit special dot member: complex, polar, vec3, vec4
3486//-----------------------------------------------------------------------------
3487t_CKBOOL emit_engine_emit_exp_dot_member_special( Chuck_Emitter * emit,
3488 a_Exp_Dot_Member member )
3489{
3490 // whether to emit addr or value
3491 t_CKBOOL emit_addr = member->self->emit_var;
3492
3493 // special case: complex and polar
3494 if( member->t_base->xid == te_complex )
3495 {
3496 // mark to emit addr
3497 if( member->base->s_meta == ae_meta_var )
3498 member->base->emit_var = TRUE;
3499 else if( emit_addr )
3500 {
3501 EM_error2( member->base->linepos,
3502 "(emit): cannot assign value to literal 'complex' value..." );
3503 return FALSE;
3504 }
3505
3506 // emit the base
3507 if( !emit_engine_emit_exp( emit, member->base ) )
3508 return FALSE;
3509
3510 string str = S_name(member->xid);
3511 // check
3512 if( str == "re" )
3513 emit->append( new Chuck_Instr_Dot_Cmp_First( member->base->s_meta == ae_meta_var, emit_addr ) );
3514 else if( str == "im" )
3515 emit->append( new Chuck_Instr_Dot_Cmp_Second( member->base->s_meta == ae_meta_var, emit_addr ) );
3516 else
3517 goto check_func;
3518
3519 // done
3520 return TRUE;
3521 }
3522 else if( member->t_base->xid == te_polar )
3523 {
3524 // mark to emit addr
3525 if( member->base->s_meta == ae_meta_var )
3526 member->base->emit_var = TRUE;
3527 else if( emit_addr )
3528 {
3529 EM_error2( member->base->linepos,
3530 "(emit): cannot assign value to literal 'polar' value..." );
3531 return FALSE;
3532 }
3533
3534 // emit the base
3535 if( !emit_engine_emit_exp( emit, member->base ) )
3536 return FALSE;
3537
3538 string str = S_name(member->xid);
3539 // check
3540 if( str == "mag" )
3541 emit->append( new Chuck_Instr_Dot_Cmp_First( member->base->s_meta == ae_meta_var, emit_addr ) );
3542 else if( str == "phase" )
3543 emit->append( new Chuck_Instr_Dot_Cmp_Second( member->base->s_meta == ae_meta_var, emit_addr ) );
3544 else
3545 goto check_func;
3546
3547 // done
3548 return TRUE;
3549 }
3550 else if( member->t_base->xid == te_vec3 || member->t_base->xid == te_vec4 )
3551 {
3552 // mark to emit addr
3553 if( member->base->s_meta == ae_meta_var )
3554 member->base->emit_var = TRUE;
3555 else if( emit_addr )
3556 {
3557 EM_error2( member->base->linepos,
3558 "(emit): cannot assign value to literal '%s' value...",
3559 member->t_base->c_name() );
3560 return FALSE;
3561 }
3562
3563 // emit the base
3564 if( !emit_engine_emit_exp( emit, member->base ) )
3565 return FALSE;
3566
3567 string str = S_name(member->xid);
3568 // check for .xyz[w] .rgb[a] .value/goal/slew
3569 if( str == "x" || str == "r" || str == "value" )
3570 emit->append( new Chuck_Instr_Dot_Cmp_First( member->base->s_meta == ae_meta_var, emit_addr ) );
3571 else if( str == "y" || str == "g" || str == "goal" )
3572 emit->append( new Chuck_Instr_Dot_Cmp_Second( member->base->s_meta == ae_meta_var, emit_addr ) );
3573 else if( str == "z" || str == "b" || str == "slew" )
3574 emit->append( new Chuck_Instr_Dot_Cmp_Third( member->base->s_meta == ae_meta_var, emit_addr ) );
3575 else if( member->t_base->xid == te_vec4 && ( str == "w" || str == "a" ) )
3576 emit->append( new Chuck_Instr_Dot_Cmp_Fourth( member->base->s_meta == ae_meta_var, emit_addr ) );
3577 else
3578 goto check_func;
3579
3580 // done
3581 return TRUE;
3582 }
3583
3584 // should not get here
3585 EM_error2( member->base->linepos,
3586 "(emit): internal error in lit_special()..." );
3587
3588 return FALSE;
3589
3590//-----------------------------------------------------------------------------
3591// goto: check for special member functions, 1.3.5.3
3592//-----------------------------------------------------------------------------
3593check_func:
3594
3595 // the type of the base
3596 Chuck_Type * t_base = member->t_base;
3597 // is the base a class/namespace or a variable
3598 t_CKBOOL base_static = isa( member->t_base, emit->env->t_class );
3599 // a function
3600 Chuck_Func * func = NULL;
3601 // a non-function value
3602 Chuck_Value * value = NULL;
3603 // the offset
3604 t_CKUINT offset = 0;
3605
3606 // check error
3607 if( base_static )
3608 {
3609 // should not get here
3610 EM_error2( member->base->linepos,
3611 "(emit): internal error in lit_special(): base static" );
3612 // done
3613 return FALSE;
3614 }
3615
3616 if( !isfunc( emit->env, member->self->type ) )
3617 {
3618 // should not get here
3619 EM_error2( member->base->linepos,
3620 "(emit): internal error in lit_special(): not member func" );
3621 // done
3622 return FALSE;
3623 }
3624
3625 // get the func
3626 value = type_engine_find_value( t_base, member->xid );
3627 func = value->func_ref;
3628 // make sure it's there
3629 assert( func != NULL );
3630
3631 // NOTE: base already emitted earier in this function (and as var)
3632
3633 // check base; 1.3.5.3
3634 if( member->base->s_meta == ae_meta_value ) // is literal
3635 {
3636 // dup the value as pointer (as faux-'this' pointer)
3637 emit->append( new Chuck_Instr_Reg_Dup_Last_As_Pointer( t_base->size / sz_WORD ) );
3638 }
3639 else // normal object
3640 {
3641 // dup the base pointer (as 'this' argument -- special case primitive)
3642 emit->append( new Chuck_Instr_Reg_Dup_Last );
3643 }
3644
3645 // find the offset for virtual table
3646 offset = func->vt_index;
3647 // emit the function
3648 emit->append( new Chuck_Instr_Dot_Primitive_Func( (t_CKUINT)func ) );
3649
3650 return TRUE;
3651}
3652
3653
3654
3655
3656//-----------------------------------------------------------------------------
3657// name: emit_engine_emit_dot_member()
3658// desc: ...
3659//-----------------------------------------------------------------------------
3660t_CKBOOL emit_engine_emit_exp_dot_member( Chuck_Emitter * emit,
3661 a_Exp_Dot_Member member )
3662{
3663 // the type of the base
3664 Chuck_Type * t_base = NULL;
3665 // whether to emit addr or value
3666 t_CKBOOL emit_addr = member->self->emit_var;
3667 // is the base a class/namespace or a variable
3668 t_CKBOOL base_static = isa( member->t_base, emit->env->t_class );
3669 // a function
3670 Chuck_Func * func = NULL;
3671 // a non-function value
3672 Chuck_Value * value = NULL;
3673 // the offset
3674 t_CKUINT offset = 0;
3675
3676 // the pointer
3677 Chuck_Instr * instr = NULL;
3678
3679 // type of the base
3680 t_CKUINT tbase_xid = member->t_base->xid;
3681 // switch on it
3682 switch( tbase_xid )
3683 {
3684 case te_complex:
3685 case te_polar:
3686 case te_vec3:
3687 case te_vec4:
3688 // emit special
3689 return emit_engine_emit_exp_dot_member_special( emit, member );
3690 // done
3691 break;
3692 }
3693
3694 // actual type - if base is class name its type is actually 'class'
3695 // to get the actual type use actual_type
3696 t_base = base_static ? member->t_base->actual_type : member->t_base;
3697
3698 // make sure that the base type is object
3699 assert( t_base->info != NULL );
3700
3701 // if base is static
3702 if( !base_static )
3703 {
3704 // if is a func
3705 if( isfunc( emit->env, member->self->type ) )
3706 {
3707 // get the func
3708 value = type_engine_find_value( t_base, member->xid );
3709 func = value->func_ref;
3710 // make sure it's there
3711 assert( func != NULL );
3712
3713 // is the func static?
3714 if( func->is_member )
3715 {
3716 // emit the base (TODO: return on error?)
3717 emit_engine_emit_exp( emit, member->base );
3718 // dup the base pointer (as 'this' argument)
3719 emit->append( new Chuck_Instr_Reg_Dup_Last );
3720 // find the offset for virtual table
3721 offset = func->vt_index;
3722 // emit the function
3723 emit->append( instr = new Chuck_Instr_Dot_Member_Func( offset ) );
3724 instr->set_linepos( member->linepos );
3725 }
3726 else
3727 {
3728 // emit the type
3729 emit->append( new Chuck_Instr_Reg_Push_Imm( (t_CKUINT)t_base ) );
3730 // emit the static function
3731 emit->append( new Chuck_Instr_Dot_Static_Func( func ) );
3732 }
3733 }
3734 else
3735 {
3736 // get the value
3737 // value = t_base->info->lookup_value( member->xid, FALSE );
3738 value = type_engine_find_value( t_base, member->xid );
3739 // make sure it's there
3740 assert( value != NULL );
3741
3742 // find the offset for data
3743 offset = value->offset;
3744
3745 // is the value static?
3746 if( value->is_member )
3747 {
3748 // emit the base (TODO: return on error?)
3749 emit_engine_emit_exp( emit, member->base );
3750 // lookup the member (1.3.1.0: changed to use getkindof instead of type size)
3751 emit->append( instr = new Chuck_Instr_Dot_Member_Data(
3752 offset, getkindof(emit->env, member->self->type), emit_addr ) );
3753 instr->set_linepos( member->linepos );
3754 }
3755 else
3756 {
3757 // if builtin or not
3758 if( value->addr )
3759 {
3760 // emit builtin (1.3.1.0: changed to use getkindof instead of type size)
3761 emit->append( new Chuck_Instr_Dot_Static_Import_Data(
3762 value->addr, getkindof(emit->env, member->self->type), emit_addr ) );
3763 }
3764 else
3765 {
3766 // emit the type
3767 emit->append( new Chuck_Instr_Reg_Push_Imm( (t_CKUINT)t_base ) );
3768 // emit the static value (1.3.1.0: changed to use getkindof in addition to size)
3769 emit->append( new Chuck_Instr_Dot_Static_Data(
3770 offset, member->self->type->size, getkindof(emit->env, member->self->type), emit_addr ) );
3771 }
3772 }
3773 }
3774 }
3775 else // static
3776 {
3777 // emit the type
3778 // commented out so built-in static member variables don't have an
3779 // extra thing on the stack - spencer
3780 //emit->append( new Chuck_Instr_Reg_Push_Imm( (t_CKUINT)t_base ) );
3781
3782 // if is a func
3783 if( isfunc( emit->env, member->self->type ) )
3784 {
3785 // emit the type - spencer
3786 emit->append( new Chuck_Instr_Reg_Push_Imm( (t_CKUINT)t_base ) );
3787 // get the func
3788 func = t_base->info->lookup_func( member->xid, FALSE );
3789 // make sure it's there
3790 assert( func != NULL );
3791 // emit the function
3792 emit->append( new Chuck_Instr_Dot_Static_Func( func ) );
3793 }
3794 else
3795 {
3796 // get the value
3797 value = t_base->info->lookup_value( member->xid, FALSE );
3798 // make sure it's there
3799 assert( value != NULL );
3800
3801 // if builtin
3802 if( value->addr )
3803 {
3804 // emit (1.3.1.0: changed to use getkindof instead of type size)
3805 emit->append( new Chuck_Instr_Dot_Static_Import_Data(
3806 value->addr, getkindof(emit->env, member->self->type), emit_addr ) );
3807 }
3808 else
3809 {
3810 // emit the type - spencer
3811 emit->append( new Chuck_Instr_Reg_Push_Imm( (t_CKUINT)t_base ) );
3812 // find the offset for data
3813 offset = value->offset;
3814 // emit the member (1.3.1.0: changed to use getkindof in addition to size)
3815 emit->append( new Chuck_Instr_Dot_Static_Data(
3816 offset, member->self->type->size, getkindof(emit->env, member->self->type), emit_addr ) );
3817 }
3818 }
3819 }
3820
3821 return TRUE;
3822}
3823
3824
3825
3826
3827//-----------------------------------------------------------------------------
3828// name: emit_engine_emit_exp_if()
3829// desc: ...
3830//-----------------------------------------------------------------------------
3831t_CKBOOL emit_engine_emit_exp_if( Chuck_Emitter * emit, a_Exp_If exp_if )
3832{
3833 t_CKBOOL ret = TRUE;
3834 Chuck_Instr_Branch_Op * op = NULL, * op2 = NULL;
3835
3836 // push the stack, allowing for new local variables
3837 emit->push_scope();
3838
3839 // emit the condition
3840 ret = emit_engine_emit_exp( emit, exp_if->cond );
3841 if( !ret )
3842 return FALSE;
3843
3844 // type of the condition
3845 switch( exp_if->cond->type->xid )
3846 {
3847 case te_int:
3848 // push 0
3849 emit->append( new Chuck_Instr_Reg_Push_Imm( 0 ) );
3850 op = new Chuck_Instr_Branch_Eq_int( 0 );
3851 break;
3852 case te_float:
3853 case te_dur:
3854 case te_time:
3855 // push 0
3856 emit->append( new Chuck_Instr_Reg_Push_Imm2( 0.0 ) );
3857 op = new Chuck_Instr_Branch_Eq_double( 0 );
3858 break;
3859
3860 default:
3861 EM_error2( exp_if->cond->linepos,
3862 "(emit): internal error: unhandled type '%s' in if condition",
3863 exp_if->cond->type->name.c_str() );
3864 return FALSE;
3865 }
3866
3867 if( !ret ) return FALSE;
3868
3869 // append the op
3870 emit->append( op );
3871
3872 // emit the body
3873 ret = emit_engine_emit_exp( emit, exp_if->if_exp );
3874 if( !ret )
3875 return FALSE;
3876
3877 // emit the skip to the end
3878 emit->append( op2 = new Chuck_Instr_Goto(0) );
3879
3880 // set the op's target
3881 op->set( emit->next_index() );
3882
3883 // emit the body
3884 ret = emit_engine_emit_exp( emit, exp_if->else_exp );
3885 if( !ret )
3886 return FALSE;
3887
3888 // pop stack
3889 emit->pop_scope();
3890
3891 // set the op2's target
3892 op2->set( emit->next_index() );
3893
3894 return ret;
3895}
3896
3897
3898
3899
3900//-----------------------------------------------------------------------------
3901// name: emit_engine_pre_constructor()
3902// desc: ...
3903//-----------------------------------------------------------------------------
3904t_CKBOOL emit_engine_pre_constructor( Chuck_Emitter * emit, Chuck_Type * type )
3905{
3906 // parent first pre constructor
3907 if( type->parent != NULL )
3908 emit_engine_pre_constructor( emit, type->parent );
3909
3910 // pre constructor
3911 if( type->has_constructor )
3912 {
3913 // make sure
3914 assert( type->info->pre_ctor != NULL );
3915 // append instruction
3916 emit->append( new Chuck_Instr_Pre_Constructor( type->info->pre_ctor,
3917 emit->code->frame->curr_offset ) );
3918 }
3919
3920 return TRUE;
3921}
3922
3923
3924
3925
3926//-----------------------------------------------------------------------------
3927// name: emit_engine_pre_constructor_array()
3928// desc: ...
3929//-----------------------------------------------------------------------------
3930t_CKBOOL emit_engine_pre_constructor_array( Chuck_Emitter * emit, Chuck_Type * type )
3931{
3932 // alloc should have put all objects to made in linear list, on stack
3933 Chuck_Instr_Pre_Ctor_Array_Top * top = NULL;
3934 Chuck_Instr_Pre_Ctor_Array_Bottom * bottom = NULL;
3935 // get start index
3936 t_CKUINT start_index = emit->next_index();
3937 // append first part of pre ctor
3938 emit->append( top = new Chuck_Instr_Pre_Ctor_Array_Top( type ) );
3939 // call pre constructor
3940 emit_engine_pre_constructor( emit, type );
3941 // append second part of the pre ctor
3942 emit->append( bottom = new Chuck_Instr_Pre_Ctor_Array_Bottom );
3943 // set the goto of the first one
3944 top->set( emit->next_index() );
3945 // set the goto for the second one
3946 bottom->set( start_index );
3947 // clean up code
3948 emit->append( new Chuck_Instr_Pre_Ctor_Array_Post );
3949
3950 return TRUE;
3951}
3952
3953
3954
3955//-----------------------------------------------------------------------------
3956// name: emit_engine_instantiate_object()
3957// desc: ...
3958//-----------------------------------------------------------------------------
3959t_CKBOOL emit_engine_instantiate_object( Chuck_Emitter * emit, Chuck_Type * type,
3960 a_Array_Sub array, t_CKBOOL is_ref )
3961{
3962 // if array
3963 if( type->array_depth )
3964 {
3965 // emit indices
3966 emit_engine_emit_exp( emit, array->exp_list );
3967 // emit array allocation
3968 Chuck_Instr * instr = NULL;
3969 emit->append( instr = new Chuck_Instr_Array_Alloc( emit->env,
3970 type->array_depth, type->array_type, emit->code->frame->curr_offset,
3971 is_ref ) );
3972 instr->set_linepos( array->linepos );
3973
3974 // handle constructor
3975 if( isobj( emit->env, type->array_type ) && !is_ref )
3976 {
3977 // call pre constructor for array
3978 emit_engine_pre_constructor_array( emit, type->array_type );
3979 }
3980 }
3981 else if( !is_ref ) // not array
3982 {
3983 // emit object instantiation code, include pre constructor
3984 emit->append( new Chuck_Instr_Instantiate_Object( type ) );
3985
3986 // call pre constructor
3987 emit_engine_pre_constructor( emit, type );
3988 }
3989
3990 return TRUE;
3991}
3992
3993
3994
3995
3996//-----------------------------------------------------------------------------
3997// name: emit_engine_emit_exp_decl()
3998// desc: ...
3999//-----------------------------------------------------------------------------
4000t_CKBOOL emit_engine_emit_exp_decl( Chuck_Emitter * emit, a_Exp_Decl decl,
4001 t_CKBOOL first_exp )
4002{
4003 a_Var_Decl_List list = decl->var_decl_list;
4004 a_Var_Decl var_decl = NULL;
4005 Chuck_Value * value = NULL;
4006 Chuck_Type * type = NULL;
4007 Chuck_Local * local = NULL;
4008 t_CKBOOL is_obj = FALSE;
4009 t_CKBOOL is_ref = FALSE;
4010 t_CKBOOL is_init = FALSE;
4011
4012 t_CKTYPE t = type_engine_find_type( emit->env, decl->type->xid );
4013 te_ExternalType externalType;
4014
4015 if( decl->is_external )
4016 {
4017 if( isa( t, emit->env->t_int ) )
4018 {
4019 externalType = te_externalInt;
4020 }
4021 else if( isa( t, emit->env->t_float ) )
4022 {
4023 externalType = te_externalFloat;
4024 }
4025 else if( isa( t, emit->env->t_event ) )
4026 {
4027 // kind-of-event (te_Type for this would be te_user, which is not helpful)
4028 externalType = te_externalEvent;
4029 }
4030 else
4031 {
4032 // fail if type unsupported
4033 EM_error2( decl->linepos, (std::string("unsupported type for external keyword: ") + t->name).c_str() );
4034 EM_error2( decl->linepos, "... (supported types: int, float, Event)" );
4035 return FALSE;
4036 }
4037 }
4038
4039 // loop through vars
4040 while( list )
4041 {
4042 // the var
4043 var_decl = list->var_decl;
4044 // get the value determined in type checker
4045 value = var_decl->value;
4046 // get the type of the value
4047 type = value->type;
4048 // is the variable a reference
4049 is_obj = isobj( emit->env, type );
4050 // do alloc or not
4051 is_ref = decl->type->ref;
4052 // not init
4053 is_init = FALSE;
4054
4055 // if this is an object
4056 if( is_obj )
4057 {
4058 // if array, then check to see if empty []
4059 if( list->var_decl->array )
4060 {
4061 if( list->var_decl->array->exp_list )
4062 {
4063 // set
4064 is_init = TRUE;
4065 // instantiate object, including array
4066 if( !emit_engine_instantiate_object( emit, type, list->var_decl->array, is_ref ) )
4067 return FALSE;
4068 }
4069 }
4070 else if( !is_ref )
4071 {
4072 // REFACTOR-2017: don't emit instructions to instantiate
4073 // external variables -- they are init/instantiated
4074 // during emit (see below in this function)
4075 if( !decl->is_external )
4076 {
4077 // set
4078 is_init = TRUE;
4079 // instantiate object (not array)
4080 if( !emit_engine_instantiate_object( emit, type, list->var_decl->array, is_ref ) )
4081 return FALSE;
4082 }
4083 }
4084 }
4085
4086 // if not init and first exp
4087 /* if( !is_init && first_exp )
4088 {
4089 // push 0
4090 if( type->size == sz_INT ) // ISSUE: 64-bit
4091 emit->append( new Chuck_Instr_Reg_Push_Imm( 0 ) );
4092 else if( type->size == sz_FLOAT ) // ISSUE: 64-bit
4093 emit->append( new Chuck_Instr_Reg_Push_Imm2( 0.0 ) );
4094 else if( type->size == sz_COMPLEX ) // ISSUE: 64-bit
4095 emit->append( new Chuck_Instr_Reg_Push_Imm4( 0.0, 0.0 ) );
4096 else
4097 {
4098 EM_error2( decl->linepos,
4099 "(emit): unhandle decl size of '%i'...",
4100 type->size );
4101 return FALSE;
4102 }
4103 }*/
4104
4105 // put in the value
4106
4107 // member
4108 if( value->is_member )
4109 {
4110 // zero out location in object, and leave addr on operand stack
4111 // added 1.3.1.0: iskindofint -- on some 64-bit systems, sz_int == sz_FLOAT
4112 if( type->size == sz_INT && iskindofint(emit->env, type) ) // ISSUE: 64-bit (fixed 1.3.1.0)
4113 emit->append( new Chuck_Instr_Alloc_Member_Word( value->offset ) );
4114 else if( type->size == sz_FLOAT ) // ISSUE: 64-bit (fixed 1.3.1.0)
4115 emit->append( new Chuck_Instr_Alloc_Member_Word2( value->offset ) );
4116 else if( type->size == sz_COMPLEX ) // ISSUE: 64-bit (fixed 1.3.1.0)
4117 emit->append( new Chuck_Instr_Alloc_Member_Word4( value->offset ) );
4118 else if( type->size == sz_VEC3 ) // ge: added 1.3.5.3
4119 emit->append( new Chuck_Instr_Alloc_Member_Vec3( value->offset ) );
4120 else if( type->size == sz_VEC4 ) // ge: added 1.3.5.3
4121 emit->append( new Chuck_Instr_Alloc_Member_Vec4( value->offset) );
4122 else
4123 {
4124 EM_error2( decl->linepos,
4125 "(emit): internal error: unhandled decl size of '%i'...",
4126 type->size );
4127 return FALSE;
4128 }
4129 }
4130 else // not member
4131 {
4132 // not in class
4133 if( !emit->env->class_def || !decl->is_static )
4134 {
4135 // allocate a place on the local stack
4136 // (added 1.3.0.0 -- is_obj for tracking objects ref count on stack)
4137 local = emit->alloc_local( type->size, value->name,
4138 is_ref, is_obj, decl->is_external );
4139 if( !local )
4140 {
4141 EM_error2( decl->linepos,
4142 "(emit): internal error: cannot allocate local '%s'...",
4143 value->name.c_str() );
4144 return FALSE;
4145 }
4146
4147 // put in the value
4148 value->offset = local->offset;
4149
4150 // REFACTOR-2017: external declaration
4151 if( decl->is_external )
4152 {
4153 Chuck_Instr_Alloc_Word_External * instr = new Chuck_Instr_Alloc_Word_External();
4154 instr->m_name = value->name;
4155 instr->m_type = externalType;
4156 instr->set_linepos( decl->linepos );
4157 emit->append( instr );
4158
4159 // if it's an event, we need to initialize it and check if the exact type matches
4160 if( externalType == te_externalEvent )
4161 {
4162 // init and construct it now!
4163 if( !emit->env->vm()->init_external_event( value->name, t ) )
4164 {
4165 // if the type doesn't exactly match (different kinds of Event), then fail.
4166 EM_error2( decl->linepos,
4167 "(emit): external Event '%s' has different type '%s' than already existing external Event of the same name",
4168 value->name.c_str(), t->name.c_str() );
4169 return FALSE;
4170 }
4171 }
4172
4173 }
4174 // zero out location in memory, and leave addr on operand stack
4175 // TODO: this is wrong for static
4176 // BAD:
4177 // FIX:
4178 // added 1.3.1.0: iskindofint -- since on some 64-bit systems, sz_INT == sz_FLOAT
4179 else if( type->size == sz_INT && iskindofint(emit->env, type) ) // ISSUE: 64-bit (fixed 1.3.1.0)
4180 {
4181 // (added 1.3.0.0 -- is_obj)
4182 Chuck_Instr_Alloc_Word * instr = new Chuck_Instr_Alloc_Word( local->offset, is_obj );
4183 instr->set_linepos( decl->linepos );
4184 emit->append( instr );
4185 }
4186 else if( type->size == sz_FLOAT ) // ISSUE: 64-bit (fixed 1.3.1.0)
4187 {
4188 Chuck_Instr_Alloc_Word2 * instr = new Chuck_Instr_Alloc_Word2( local->offset );
4189 instr->set_linepos( decl->linepos );
4190 emit->append( instr );
4191 }
4192 else if( type->size == sz_COMPLEX ) // ISSUE: 64-bit (fixed 1.3.1.0)
4193 {
4194 emit->append( new Chuck_Instr_Alloc_Word4( local->offset ) );
4195 }
4196 else if( type->size == sz_VEC3 ) // ge: added 1.3.5.3
4197 {
4198 emit->append( new Chuck_Instr_Alloc_Vec3(local->offset) );
4199 }
4200 else if( type->size == sz_VEC4 ) // ge: added 1.3.5.3
4201 {
4202 emit->append( new Chuck_Instr_Alloc_Vec4(local->offset) );
4203 }
4204 else
4205 {
4206 EM_error2( decl->linepos,
4207 "(emit): internal error: unhandled decl size of '%i'...",
4208 type->size );
4209 return FALSE;
4210 }
4211 }
4212 else // static
4213 {
4214 // emit the type
4215 emit->append( new Chuck_Instr_Reg_Push_Imm( (t_CKUINT)emit->env->class_def ) );
4216 // emit the static value (1.3.1.0: changed to use getkindof in addition to size)
4217 emit->append( new Chuck_Instr_Dot_Static_Data(
4218 value->offset, value->type->size, getkindof(emit->env, value->type), TRUE ) );
4219 }
4220 }
4221
4222 // set is_init
4223 is_init = FALSE;
4224
4225 // if object, assign
4226 if( is_obj )
4227 {
4228 // if array
4229 if( var_decl->array )
4230 {
4231 // if not []
4232 if( var_decl->array->exp_list )
4233 {
4234 // set
4235 is_init = TRUE;
4236 // assign
4237 emit->append( new Chuck_Instr_Assign_Object );
4238 }
4239 }
4240 else if( !is_ref )
4241 {
4242 // REFACTOR-2017: don't add an Assign_Object instruction for
4243 // external objects -- they should be instantiated during emit,
4244 // not during runtime and therefore don't need an assign instr
4245 if( !decl->is_external )
4246 {
4247 // set
4248 is_init = TRUE;
4249 // assign the object
4250 emit->append( new Chuck_Instr_Assign_Object );
4251 }
4252 }
4253 }
4254
4255 // if not init and first exp
4256 /* if( !is_init && first_exp )
4257 {
4258 // if obj
4259 if( is_obj )
4260 emit->append( new Chuck_Instr_Assign_Object );
4261 // size 4 primitive
4262 // added 1.3.1.0: iskindofint -- since on some 64-bit systems, sz_INT == sz_FLOAT
4263 else if( type->size == sz_INT && iskindofint(type) ) // ISSUE: 64-bit (fixed 1.3.1.0)
4264 emit->append( new Chuck_Instr_Assign_Primitive );
4265 // size 8 primitive
4266 else if( type->size == sz_FLOAT ) // ISSUE: 64-bit (fixed 1.3.1.0)
4267 emit->append( new Chuck_Instr_Assign_Primitive2 );
4268 // size 16 primitive
4269 else if( type->size == sz_COMPLEX ) // ISSUE: 64-bit (fixed 1.3.1.0)
4270 emit->append( new Chuck_Instr_Assign_Primitive4 );
4271 else
4272 assert( FALSE );
4273 }*/
4274
4275 list = list->next;
4276 }
4277
4278 return TRUE;
4279}
4280
4281
4282
4283
4284//-----------------------------------------------------------------------------
4285// name: emit_engine_emit_code_segment()
4286// desc: ...
4287//-----------------------------------------------------------------------------
4288t_CKBOOL emit_engine_emit_code_segment( Chuck_Emitter * emit,
4289 a_Stmt_Code stmt, t_CKBOOL push )
4290{
4291 a_Stmt_List list = stmt->stmt_list;
4292
4293 // loop through
4294 while( list )
4295 {
4296 // emit the statement
4297 if( !emit_engine_emit_stmt( emit, list->stmt ) )
4298 return FALSE;
4299
4300 // next
4301 list = list->next;
4302 }
4303
4304 // TODO: push
4305
4306 return TRUE;
4307}
4308
4309
4310
4311
4312//-----------------------------------------------------------------------------
4313// name: emit_engine_emit_func_def()
4314// desc: ...
4315//-----------------------------------------------------------------------------
4316t_CKBOOL emit_engine_emit_func_def( Chuck_Emitter * emit, a_Func_Def func_def )
4317{
4318 // get the func
4319 Chuck_Func * func = func_def->ck_func;
4320 // get the value
4321 Chuck_Value * value = func->value_ref;
4322 // get the type
4323 Chuck_Type * type = value->type;
4324 // local
4325 Chuck_Local * local = NULL;
4326
4327 // make sure it's the same one
4328 //Chuck_Func * func2 = emit->env->context->nspc.lookup_func( func_def->name, FALSE );
4329 //if( func != func2 )
4330 //{
4331 // EM_error2( func_def->linepos,
4332 // "(emit): ambiguous function resolution for %s...",
4333 // S_name(func_def->name) );
4334 // return FALSE;
4335 //}
4336
4337 // make sure the code is empty
4338 if( func->code != NULL )
4339 {
4340 EM_error2( func_def->linepos,
4341 "(emit): function '%s' already emitted...",
4342 S_name(func_def->name) );
4343 return FALSE;
4344 }
4345
4346 // make sure we are not in a function already
4347 if( emit->env->func != NULL )
4348 {
4349 EM_error2( func_def->linepos,
4350 "(emit): internal error: nested function definition..." );
4351 return FALSE;
4352 }
4353
4354 // if not part of a class
4355 if( !emit->env->class_def )
4356 {
4357 // put function on stack
4358 // ge: added FALSE to the 'is_obj' argument, 2012 april (added 1.3.0.0)
4359 local = emit->alloc_local( value->type->size, value->name, TRUE, FALSE, FALSE );
4360 // remember the offset
4361 value->offset = local->offset;
4362 // write to mem stack
4363 emit->append( new Chuck_Instr_Mem_Set_Imm( value->offset, (t_CKUINT)func ) );
4364 }
4365
4366 // set the func
4367 emit->env->func = func;
4368 // push the current code
4369 emit->stack.push_back( emit->code );
4370 // make a new one
4371 emit->code = new Chuck_Code;
4372 // name the code
4373 emit->code->name = emit->env->class_def ? emit->env->class_def->name + "." : "";
4374 emit->code->name += func->name + "( ... )";
4375 // set whether need this
4376 emit->code->need_this = func->is_member;
4377 // keep track of full path (added 1.3.0.0)
4378 emit->code->filename = emit->context->full_path;
4379
4380 // go through the args
4381 a_Arg_List a = func_def->arg_list;
4382 t_CKBOOL is_obj = FALSE; // (added 1.3.0.0)
4383 t_CKBOOL is_ref = FALSE;
4384
4385 // if member (non-static) function
4386 if( func->is_member )
4387 {
4388 // get the size
4389 emit->code->stack_depth += sizeof(t_CKUINT);
4390 // add this
4391 // ge: added FALSE to the 'is_obj' argument, 2012 april (added 1.3.0.0)
4392 if( !emit->alloc_local( sizeof(t_CKUINT), "this", TRUE, FALSE, FALSE ) )
4393 {
4394 EM_error2( a->linepos,
4395 "(emit): internal error: cannot allocate local 'this'..." );
4396 return FALSE;
4397 }
4398 }
4399
4400 // ge: 2012 april: added push scope (added 1.3.0.0)
4401 emit->push_scope();
4402
4403 // loop through args
4404 while( a )
4405 {
4406 // get the value
4407 value = a->var_decl->value;
4408 // get the type
4409 type = value->type;
4410 // is object? (added ge: 2012 april | added 1.3.0.0)
4411 is_obj = isobj( emit->env, type );
4412 // get ref
4413 is_ref = a->type_decl->ref;
4414 // get the size
4415 emit->code->stack_depth += type->size;
4416 // allocate a place on the local stack
4417 // ge: added 'is_obj' 2012 april
4418 local = emit->alloc_local( type->size, value->name, is_ref, is_obj, FALSE );
4419 if( !local )
4420 {
4421 EM_error2( a->linepos,
4422 "(emit): internal error: cannot allocate local '%s'...",
4423 value->name.c_str() );
4424 return FALSE;
4425 }
4426 // remember the offset
4427 value->offset = local->offset;
4428
4429 // advance
4430 a = a->next;
4431 }
4432
4433 // TODO: make sure the calculated stack depth is the same as func_def->stack depth
4434 // taking into account member function
4435
4436 // add references for objects in the arguments (added 1.3.0.0)
4437 // NOTE: this isn't in use since currently the caller is reference counting
4438 // the arguments -- this is to better support sporking, which is more
4439 // asynchronous. the code below is left in as reference for callee ref counting
4440 // emit->addref_on_scope();
4441
4442 // emit the code
4443 if( !emit_engine_emit_stmt( emit, func_def->code, FALSE ) )
4444 return FALSE;
4445
4446 // added by spencer June 2014 (1.3.5.0)
4447 // ensure return
4448 if( func_def->ret_type && func_def->ret_type != emit->env->t_void )
4449 {
4450 emit->append( new Chuck_Instr_Reg_Push_Imm(0) );
4451
4452 Chuck_Instr_Goto * instr = new Chuck_Instr_Goto( 0 );
4453 emit->append( instr );
4454 emit->code->stack_return.push_back( instr );
4455 }
4456
4457 // ge: pop scope (2012 april | added 1.3.0.0)
4458 // TODO: ge 2012 april: pop scope? clean up function arguments? are argument properly ref counted?
4459 emit->pop_scope();
4460
4461 // set the index for next instruction for return statements
4462 for( t_CKUINT i = 0; i < emit->code->stack_return.size(); i++ )
4463 emit->code->stack_return[i]->set( emit->next_index() );
4464 // clear the return stack
4465 emit->code->stack_return.clear();
4466 // emit return statement
4467 emit->append( new Chuck_Instr_Func_Return );
4468
4469 // vm code
4470 func->code = emit_to_code( emit->code, NULL, emit->dump );
4471 // add reference
4472 func->code->add_ref();
4473
4474 // unset the func
4475 emit->env->func = NULL;
4476 // delete the code
4477 SAFE_DELETE( emit->code );
4478 // pop the code
4479 assert( emit->stack.size() );
4480 emit->code = emit->stack.back();
4481 emit->stack.pop_back();
4482
4483 return TRUE;
4484}
4485
4486
4487
4488
4489//-----------------------------------------------------------------------------
4490// name: emit_engine_emit_class_def()
4491// desc: ...
4492//-----------------------------------------------------------------------------
4493t_CKBOOL emit_engine_emit_class_def( Chuck_Emitter * emit, a_Class_Def class_def )
4494{
4495 // get the type
4496 Chuck_Type * type = class_def->type;
4497 // the return type
4498 t_CKBOOL ret = TRUE;
4499 // the class body
4500 a_Class_Body body = class_def->body;
4501
4502 // make sure the code is empty
4503 if( type->info->pre_ctor != NULL && type->info->pre_ctor->instr != NULL )
4504 {
4505 EM_error2( class_def->linepos,
4506 "(emit): class '%s' already emitted...",
4507 type->name.c_str() );
4508 return FALSE;
4509 }
4510
4511 // make sure we are not in a class already
4512 //if( emit->env->class_def != NULL )
4513 //{
4514 // EM_error2( class_def->linepos,
4515 // "(emit): internal error: nested class definition..." );
4516 // return FALSE;
4517 //}
4518
4519 // set the class
4520 emit->env->class_stack.push_back( emit->env->class_def );
4521 emit->env->class_def = type;
4522 // push the current code
4523 emit->stack.push_back( emit->code );
4524 // make a new one
4525 emit->code = new Chuck_Code;
4526 // name the code
4527 emit->code->name = string("class ") + type->name;
4528 // whether code needs this
4529 emit->code->need_this = TRUE;
4530 // if has constructor
4531 // if( type->has_constructor ) type->info->pre_ctor = new Chuck_VM_Code;
4532 // keep track of full path (added 1.3.0.0)
4533 emit->code->filename = emit->context->full_path;
4534
4535 // get the size
4536 emit->code->stack_depth += sizeof(t_CKUINT);
4537 // add this
4538 // ge: added TRUE to the 'is_obj' argument, 2012 april (added 1.3.0.0)
4539 // TODO: verify this is right, and not over-ref counted / cleaned up?
4540 if( !emit->alloc_local( sizeof(t_CKUINT), "this", TRUE, TRUE, FALSE ) )
4541 {
4542 EM_error2( class_def->linepos,
4543 "(emit): internal error: cannot allocate local 'this'..." );
4544 return FALSE;
4545 }
4546
4547 // emit the body
4548 while( body && ret )
4549 {
4550 // check the section
4551 switch( body->section->s_type )
4552 {
4553 case ae_section_stmt:
4554 ret = emit_engine_emit_stmt_list( emit, body->section->stmt_list );
4555 break;
4556
4557 case ae_section_func:
4558 ret = emit_engine_emit_func_def( emit, body->section->func_def );
4559 break;
4560
4561 case ae_section_class:
4562 ret = emit_engine_emit_class_def( emit, body->section->class_def );
4563 //EM_error2( body->section->class_def->linepos,
4564 // "nested class definitions are not yet supported..." );
4565 //ret = FALSE;
4566 break;
4567 }
4568
4569 // move to the next section
4570 body = body->next;
4571 }
4572
4573 // if ok
4574 if( ret )
4575 {
4576 // emit return statement
4577 emit->append( new Chuck_Instr_Func_Return );
4578 // vm code
4579 type->info->pre_ctor = emit_to_code( emit->code, type->info->pre_ctor, emit->dump );
4580 // add reference
4581 type->info->pre_ctor->add_ref();
4582 // allocate static
4583 type->info->class_data = new t_CKBYTE[type->info->class_data_size];
4584 // verify
4585 if( !type->info->class_data )
4586 {
4587 // we have a problem
4588 CK_FPRINTF_STDERR(
4589 "[chuck](emitter): OutOfMemory: while allocating static data '%s'\n", type->c_name() );
4590 // flag
4591 ret = FALSE;
4592 }
4593 else
4594 {
4595 // zero it out
4596 memset( type->info->class_data, 0, type->info->class_data_size );
4597 }
4598 }
4599
4600 // check again
4601 if( !ret )
4602 {
4603 // clean
4604 SAFE_DELETE( type->info->pre_ctor );
4605 }
4606
4607 // unset the class
4608 emit->env->class_def = emit->env->class_stack.back();
4609 emit->env->class_stack.pop_back();
4610 // delete the code
4611 SAFE_DELETE( emit->code );
4612 // pop the code
4613 assert( emit->stack.size() );
4614 emit->code = emit->stack.back();
4615 emit->stack.pop_back();
4616
4617 return ret;
4618}
4619
4620
4621
4622
4623//-----------------------------------------------------------------------------
4624// name: emit_engine_emit_spork()
4625// desc: ...
4626//-----------------------------------------------------------------------------
4627t_CKBOOL emit_engine_emit_spork( Chuck_Emitter * emit, a_Exp_Func_Call exp )
4628{
4629 // spork
4630 Chuck_Instr_Mem_Push_Imm * op = NULL;
4631
4632 // if member function, push this
4633 // TODO: this is a hack - what if exp is not func_call?
4634 // if( exp->ck_func->is_member )
4635 // emit->append( new Chuck_Instr_Reg_Push_This );
4636
4637 // evaluate args on sporker shred
4638 if( !emit_engine_emit_func_args( emit, exp ) )
4639 return FALSE;
4640
4641 // emit func pointer on sporker shred
4642 if( !emit_engine_emit_exp( emit, exp->func ) )
4643 {
4644 EM_error2( exp->linepos,
4645 "(emit): internal error in evaluating function call..." );
4646 return FALSE;
4647 }
4648
4649 // push the current code
4650 emit->stack.push_back( emit->code );
4651 // make a new one (spork~exp shred)
4652 emit->code = new Chuck_Code;
4653 // handle need this
4654 emit->code->need_this = exp->ck_func->is_member;
4655 // name it: e.g. spork~foo [line 5]
4656 std::ostringstream name;
4657 name << "spork~"
4658 << exp->ck_func->name.substr( 0, exp->ck_func->name.find( "@" ))
4659 << " [line " << exp->linepos << "]";
4660 emit->code->name = name.str();
4661 // keep track of full path (added 1.3.0.0)
4662 emit->code->filename = emit->context->full_path;
4663 // push op
4664 op = new Chuck_Instr_Mem_Push_Imm( 0 );
4665 // emit the stack depth - we don't know this yet
4666 emit->append( op );
4667
4668 // call the func on sporkee shred
4669 if( !emit_engine_emit_exp_func_call(
4670 emit,
4671 exp->ck_func,
4672 exp->ret_type,
4673 exp->linepos,
4674 TRUE ) )
4675 return FALSE;
4676
4677 // emit the function call, with special flag
4678 // if( !emit_engine_emit_exp_func_call( emit, exp, TRUE ) )
4679 // return FALSE;
4680
4681 // done
4682 emit->append( new Chuck_Instr_EOC );
4683 // set the stack depth now that we know
4684 op->set( emit->code->stack_depth );
4685
4686 // emit it
4687 Chuck_VM_Code * code = emit_to_code( emit->code, NULL, emit->dump );
4688 // remember it
4689 exp->ck_vm_code = code;
4690 // add reference
4691 exp->ck_vm_code->add_ref();
4692 // code->name = string("spork~exp");
4693
4694 // restore the code to sporker shred
4695 assert( emit->stack.size() > 0 );
4696 emit->code = emit->stack.back();
4697 // pop
4698 emit->stack.pop_back();
4699
4700 a_Exp e = exp->args;
4701 t_CKUINT size = 0;
4702 while( e ) { size += e->cast_to ? e->cast_to->size : e->type->size; e = e->next; }
4703
4704 // handle member function
4705 // TODO: this is a hack - what if exp is not func_call?
4706 // if( emit->code->need_this )
4707 // size += sz_INT; // (changed 1.3.1.0: 4 to sz_INT)
4708
4709 // emit instruction that will put the code on the stack
4710 emit->append( new Chuck_Instr_Reg_Push_Imm( (t_CKUINT)code ) );
4711 // emit spork instruction - this will copy, func, args, this
4712 emit->append( new Chuck_Instr_Spork( size ) );
4713
4714 return TRUE;
4715}
4716
4717
4718
4719
4720//-----------------------------------------------------------------------------
4721// name: emit_engine_emit_spork()
4722// desc: ...
4723//-----------------------------------------------------------------------------
4724//t_CKBOOL emit_engine_emit_spork( Chuck_Emitter * emit, a_Stmt stmt )
4725//{
4726// // push the current code
4727// emit->stack.push_back( emit->code );
4728// // make a new one (spork~exp shred)
4729// emit->code = new Chuck_Code;
4730// // handle need this
4731// emit->code->need_this = emit->env->class_def ? TRUE : FALSE;
4732// // name it
4733// emit->code->name = "spork~exp";
4734// // keep track of full path (added 1.3.0.0)
4735// emit->code->filename = emit->context->full_path;
4736//
4737// // call the code on sporkee shred
4738// if( !emit_engine_emit_stmt( emit, stmt, TRUE ) )
4739// return FALSE;
4740//
4741// // done
4742// emit->append( new Chuck_Instr_EOC );
4743//
4744// // emit it
4745// Chuck_VM_Code * code = emit_to_code( emit->code, NULL, emit->dump );
4746//
4747// // restore the code to sporker shred
4748// assert( emit->stack.size() > 0 );
4749// emit->code = emit->stack.back();
4750// // pop
4751// emit->stack.pop_back();
4752//
4753// if( code->need_this )
4754// {
4755// // push this if needed
4756// emit->append( new Chuck_Instr_Reg_Push_This );
4757// }
4758// // emit instruction that will put the code on the stack
4759// emit->append( new Chuck_Instr_Reg_Push_Imm( (t_CKUINT)code ) );
4760// // emit spork instruction - this will copy, func, args, this
4761// emit->append( new Chuck_Instr_Spork_Stmt( 0 ) );
4762//
4763// return TRUE;
4764//}
4765
4766
4767
4768
4769//-----------------------------------------------------------------------------
4770// name: emit_engine_emit_symbol()
4771// desc: ...
4772//-----------------------------------------------------------------------------
4773t_CKBOOL emit_engine_emit_symbol( Chuck_Emitter * emit, S_Symbol symbol,
4774 Chuck_Value * v, t_CKBOOL emit_var,
4775 int linepos )
4776{
4777 // look up the value
4778 // Chuck_Value * v = emit->env->curr->lookup_value( symbol, TRUE );
4779 // it should be there
4780 if( !v )
4781 {
4782 // internal error
4783 EM_error2( linepos,
4784 "(emit): internal error: undefined symbol '%s'...",
4785 S_name(symbol) );
4786 return FALSE;
4787 }
4788
4789 // if external, find what type
4790 // (due to user classes, this info is only available during emit)
4791 te_ExternalType external_type;
4792 if( v->is_external )
4793 {
4794 if( isa( v->type, emit->env->t_int ) )
4795 {
4796 external_type = te_externalInt;
4797 }
4798 else if( isa( v->type, emit->env->t_float ) )
4799 {
4800 external_type = te_externalFloat;
4801 }
4802 else if( isa( v->type, emit->env->t_event ) )
4803 {
4804 external_type = te_externalEvent;
4805 }
4806 else
4807 {
4808 // internal error
4809 EM_error2( linepos,
4810 "(emit): internal error: unknown external type '%s'...",
4811 v->type->name.c_str() );
4812 return FALSE;
4813 }
4814 }
4815
4816 // if part of class - this only works because x.y is handled separately
4817 if( v->owner_class && (v->is_member || v->is_static) )
4818 {
4819 // make sure talking about the same class
4820 // this doesn't work since the owner class could be a super class
4821 // assert( v->owner_class == emit->env->class_def );
4822 //
4823 // try this (thanks Robin Davies)
4824 assert( isa( emit->env->class_def, v->owner_class ) /* || is_global( v->owner_class ) */ );
4825
4826 // emit as this.v
4827 // BUG: passing "this" below might be bad if the exp is freed and string with it
4828 a_Exp base = new_exp_from_id( (char *)"this", linepos );
4829 a_Exp dot = new_exp_from_member_dot( base, (char *)v->name.c_str(), linepos );
4830 base->type = v->owner_class;
4831 dot->type = v->type;
4832 dot->dot_member.t_base = v->owner_class;
4833 dot->emit_var = emit_var;
4834 // emit it
4835 if( !emit_engine_emit_exp_dot_member( emit, &dot->dot_member ) )
4836 {
4837 // internal error
4838 EM_error2( linepos,
4839 "(emit): internal error: symbol transformation failed..." );
4840 return FALSE;
4841 }
4842
4843 return TRUE;
4844 }
4845
4846 // var or value
4847 if( emit_var )
4848 {
4849 // emit as addr
4850 if( v->is_external )
4851 {
4852 emit->append( new Chuck_Instr_Reg_Push_External_Addr( v->name, external_type ) );
4853 }
4854 else
4855 {
4856 emit->append( new Chuck_Instr_Reg_Push_Mem_Addr( v->offset, v->is_context_global ) );
4857 }
4858 }
4859 else
4860 {
4861 // special case
4862 if( v->func_ref )
4863 emit->append( new Chuck_Instr_Reg_Push_Imm( (t_CKUINT)v->func_ref ) );
4864 else if( v->is_external )
4865 {
4866 emit->append( new Chuck_Instr_Reg_Push_External( v->name, external_type ) );
4867 }
4868 // check size
4869 // (added 1.3.1.0: iskindofint -- since in some 64-bit systems, sz_INT == sz_FLOAT)
4870 else if( v->type->size == sz_INT && iskindofint(emit->env, v->type) ) // ISSUE: 64-bit (fixed 1.3.1.0)
4871 emit->append( new Chuck_Instr_Reg_Push_Mem( v->offset, v->is_context_global ) );
4872 else if( v->type->size == sz_FLOAT ) // ISSUE: 64-bit (fixed 1.3.1.0)
4873 emit->append( new Chuck_Instr_Reg_Push_Mem2( v->offset, v->is_context_global ) );
4874 else if( v->type->size == sz_COMPLEX ) // ISSUE: 64-bit (fixed 1.3.1.0)
4875 emit->append( new Chuck_Instr_Reg_Push_Mem4( v->offset, v->is_context_global ) );
4876 else if( v->type->size == sz_VEC3 ) // ge: added 1.3.5.3
4877 emit->append( new Chuck_Instr_Reg_Push_Mem_Vec3( v->offset, v->is_context_global ) );
4878 else if( v->type->size == sz_VEC4 ) // ge: added 1.3.5.3
4879 emit->append( new Chuck_Instr_Reg_Push_Mem_Vec4( v->offset, v->is_context_global ) );
4880 else
4881 {
4882 // internal error
4883 EM_error2( linepos,
4884 "(emit): internal error: symbol '%s' has size '%i'...",
4885 S_name(symbol), v->type->size );
4886 return FALSE;
4887 }
4888 }
4889
4890 return TRUE;
4891}
4892
4893
4894
4895
4896//-----------------------------------------------------------------------------
4897// name: addref_on_scope()
4898// desc: add references to locals on current scope (added 1.3.0.0)
4899//-----------------------------------------------------------------------------
4900void Chuck_Emitter::addref_on_scope()
4901{
4902 // sanity
4903 assert( code != NULL );
4904 // clear locals
4905 locals.clear();
4906 // get the current scope
4907 code->frame->get_scope( locals );
4908
4909 // iterate over locals
4910 for( int i = 0; i < locals.size(); i++ )
4911 {
4912 // get it
4913 Chuck_Local * local = locals[i];
4914 // check to see if it's an object
4915 if( local->is_obj )
4916 {
4917 // REFACTOR-2017: Don't do if local is external
4918 // Note: I don't think addref_on_scope() is used anywhere,
4919 // but I am doing this to mirror pop_scope() below, which IS used
4920 if( !local->is_external )
4921 {
4922 // emit instruction to add reference
4923 this->append( new Chuck_Instr_AddRef_Object2( local->offset ) );
4924 }
4925 }
4926 }
4927}
4928
4929
4930
4931
4932//-----------------------------------------------------------------------------
4933// name: pop_scope()
4934// desc: ...
4935//-----------------------------------------------------------------------------
4936void Chuck_Emitter::pop_scope( )
4937{
4938 // sanity
4939 assert( code != NULL );
4940 // clear locals
4941 locals.clear();
4942 // get locals
4943 code->frame->pop_scope( locals );
4944
4945 // ge (2012 april): attempt to free locals (added 1.3.0.0)
4946 // was -- TODO: free locals -- chievo!
4947 for( int i = 0; i < locals.size(); i++ )
4948 {
4949 // get local
4950 Chuck_Local * local = locals[i];
4951 // CK_STDCERR << "local: " << local->offset << " " << local->is_obj << CK_STDENDL;
4952 // check to see if it's an object
4953 if( local->is_obj )
4954 {
4955 // (REFACTOR-2017: don't release external objects)
4956 if( !local->is_external )
4957 {
4958 // emit instruction to release the object
4959 this->append( new Chuck_Instr_Release_Object2( local->offset ) );
4960 }
4961 }
4962
4963 // reclaim local; null out to be safe
4964 SAFE_DELETE( local ); locals[i] = NULL;
4965 }
4966
4967 // clear it
4968 locals.clear();
4969}
4970
4971
4972
4973
4974//-----------------------------------------------------------------------------
4975// name: find_dur()
4976// desc: ...
4977//-----------------------------------------------------------------------------
4978t_CKBOOL Chuck_Emitter::find_dur( const string & name, t_CKDUR * out )
4979{
4980 // sanity
4981 assert( env != NULL );
4982 assert( out != NULL );
4983
4984 // zero
4985 *out = 0.0;
4986 // get value from env
4987 Chuck_Value * value = env->global()->lookup_value( name, FALSE );
4988 if( !value || !equals( value->type, env->t_dur ) ) return FALSE;
4989 // copy
4990 *out = *( (t_CKDUR *)value->addr );
4991
4992 return TRUE;
4993}
4994
4995
4996
4997
4998/*
4999//-----------------------------------------------------------------------------

73 more lines aren’t shown here.

core/chuck_emit.h+0−176
@@ -1,176 +0,0 @@
1/*----------------------------------------------------------------------------
2 ChucK Concurrent, On-the-fly Audio Programming Language
3 Compiler and Virtual Machine
4
5 Copyright (c) 2004 Ge Wang and Perry R. Cook. All rights reserved.
6 http://chuck.stanford.edu/
7 http://chuck.cs.princeton.edu/
8
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.
13
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.
18
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-----------------------------------------------------------------------------*/
24
25//-----------------------------------------------------------------------------
26// file: chuck_emit.h
27// desc: chuck instruction emitter
28//
29// author: Ge Wang (ge@ccrma.stanford.edu | gewang@cs.princeton.edu)
30// date: Autumn 2002 - first version
31// Autumn 2004 - redesign
32//-----------------------------------------------------------------------------
33#ifndef __CHUCK_EMIT_H__
34#define __CHUCK_EMIT_H__
35
36#include "chuck_def.h"
37#include "chuck_oo.h"
38#include "chuck_type.h"
39#include "chuck_frame.h"
40
41
42// forward references
43struct Chuck_Instr;
44struct Chuck_Instr_Goto;
45struct Chuck_VM_Code;
46struct Chuck_VM_Shred;
47
48
49
50
51//-----------------------------------------------------------------------------
52// name: struct Chuck_Code
53// desc: ...
54//-----------------------------------------------------------------------------
55struct Chuck_Code
56{
57public:
58 // name
59 std::string name;
60 // stack depth
61 t_CKUINT stack_depth;
62 // need this
63 t_CKBOOL need_this;
64 // frame
65 Chuck_Frame * frame;
66 // code
67 std::vector<Chuck_Instr *> code;
68
69 // continue stack
70 std::vector<Chuck_Instr_Goto *> stack_cont;
71 // break stack
72 std::vector<Chuck_Instr_Goto *> stack_break;
73 // return stack
74 std::vector<Chuck_Instr_Goto *> stack_return;
75
76 // filename this code came from (added 1.3.0.0)
77 std::string filename;
78
79 // constructor
80 Chuck_Code( )
81 {
82 stack_depth = 0;
83 need_this = FALSE;
84 frame = new Chuck_Frame;
85 }
86
87 // destructor
88 ~Chuck_Code() { delete frame; frame = NULL; }
89};
90
91
92
93
94//-----------------------------------------------------------------------------
95// name: struct Chuck_Emitter
96// desc: ...
97//-----------------------------------------------------------------------------
98struct Chuck_Emitter : public Chuck_VM_Object
99{
100 // reference to the type checker environment
101 Chuck_Env * env;
102
103 // current code
104 Chuck_Code * code;
105 // current context
106 Chuck_Context * context;
107 // expression namespace
108 Chuck_Namespace * nspc;
109 // current function definition
110 Chuck_Func * func;
111
112 // code stack
113 std::vector<Chuck_Code *> stack;
114 // locals
115 std::vector<Chuck_Local *> locals;
116
117 // dump
118 t_CKBOOL dump;
119
120 // constructor
121 Chuck_Emitter()
122 { env = NULL; code = NULL; context = NULL;
123 nspc = NULL; func = NULL; dump = FALSE; }
124
125 // destructor
126 ~Chuck_Emitter()
127 { }
128
129 // append instruction
130 void append( Chuck_Instr * instr )
131 { assert( code != NULL ); code->code.push_back( instr ); }
132 // index
133 t_CKUINT next_index()
134 { assert( code != NULL ); return code->code.size(); }
135
136 // push scope
137 void push_scope( )
138 { assert( code != NULL ); code->frame->push_scope(); }
139 // alloc local (ge: added is_obj 2012 april | added 1.3.0.0)
140 Chuck_Local * alloc_local( t_CKUINT size, const std::string & name,
141 t_CKBOOL is_ref, t_CKBOOL is_obj, t_CKBOOL is_external )
142 { assert( code != NULL ); return code->frame->alloc_local( size, name,
143 is_ref, is_obj, is_external ); }
144 // add references to locals on current scope (added 1.3.0.0)
145 void addref_on_scope();
146 // pop scope
147 void pop_scope( );
148
149 // default durations
150 t_CKBOOL find_dur( const std::string & name, t_CKDUR * out );
151};
152
153
154
155
156// allocate the emitter
157Chuck_Emitter * emit_engine_init( Chuck_Env * env );
158// shutdown and free the emitter
159t_CKBOOL emit_engine_shutdown( Chuck_Emitter *& emit );
160// emit a program into vm code
161Chuck_VM_Code * emit_engine_emit_prog( Chuck_Emitter * emit,
162 a_Program prog,
163 te_HowMuch how_much = te_do_all );
164// helper function to emit code
165Chuck_VM_Code * emit_to_code( Chuck_Code * in,
166 Chuck_VM_Code * out = NULL,
167 t_CKBOOL dump = FALSE );
168
169// NOT USED: ...
170t_CKBOOL emit_engine_addr_map( Chuck_Emitter * emit, Chuck_VM_Shred * shred );
171t_CKBOOL emit_engine_resolve( );
172
173
174
175
176#endif
core/chuck_errmsg.cpp+0−650
@@ -1,650 +0,0 @@
1/*----------------------------------------------------------------------------
2 ChucK Concurrent, On-the-fly Audio Programming Language
3 Compiler and Virtual Machine
4
5 Copyright (c) 2004 Ge Wang and Perry R. Cook. All rights reserved.
6 http://chuck.stanford.edu/
7 http://chuck.cs.princeton.edu/
8
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.
13
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.
18
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-----------------------------------------------------------------------------*/
24
25//-----------------------------------------------------------------------------
26// file: errmsg.cpp
27// desc: functions used in all phases of the compiler to give error messages
28// based on Andrew Appel's Tiger code
29//
30// author: Ge Wang (ge@ccrma.stanford.edu | gewang@cs.princeton.edu)
31// based on code by: Andrew Appel (appel@cs.princeton.edu)
32// date: Summer 2002
33//-----------------------------------------------------------------------------
34#include <stdlib.h>
35#include <stdarg.h>
36#include <string.h>
37#include <sstream>
38#include <iostream>
39#include "chuck_utils.h"
40#include "chuck_errmsg.h"
41#include "util_thread.h"
42
43
44// global
45int EM_tokPos = 0;
46int EM_lineNum = 1;
47int EM_extLineNum = 1;
48t_CKBOOL anyErrors= FALSE;
49
50// local global
51static const char * fileName = "";
52static int lineNum = 1;
53static char g_buffer[1024] = "";
54static const size_t LASTERROR_SIZE = 1024;
55static char g_lasterror[LASTERROR_SIZE] = "[chuck]: (no error)";
56static size_t g_lasterrorIndex = strlen(g_lasterror);
57// log globals
58int g_loglevel = CK_LOG_CORE;
59int g_logstack = 0;
60XMutex g_logmutex;
61
62// more local globals
63static const size_t g_buffer2_size = 1024;
64static char g_buffer2[g_buffer2_size] = "";
65std::stringstream g_stdout_stream;
66std::stringstream g_stderr_stream;
67
68// local global callbacks
69void (*g_stdout_callback)(const char *) = NULL;
70void (*g_stderr_callback)(const char *) = NULL;
71
72void ck_fprintf_stdout( const char * format, ... )
73{
74 // evaluate the format string
75 va_list args;
76 va_start( args, format );
77 vsnprintf( g_buffer2, g_buffer2_size, format, args );
78 va_end( args );
79
80 // send the formatted string to the buffer
81 g_stdout_stream << g_buffer2;
82
83 // try flushing
84 ck_fflush_stdout();
85}
86
87
88void ck_fprintf_stderr( const char * format, ... )
89{
90 // evaluate the format string
91 va_list args;
92 va_start( args, format );
93 vsnprintf( g_buffer2, g_buffer2_size, format, args );
94 va_end( args );
95
96 // send the formatted string to the buffer
97 g_stderr_stream << g_buffer2;
98
99 // try flushing
100 ck_fflush_stderr();
101}
102
103
104void ck_fflush_stdout()
105{
106 // check if stream contains a newline
107 if( g_stdout_stream.str().find( '\n' ) != std::string::npos )
108 {
109 // if so, print it
110 if( g_stdout_callback == NULL ) {
111 // send to stdout
112 fprintf( stdout, "%s", g_stdout_stream.str().c_str() );
113 }
114 else
115 {
116 // emit to callback
117 g_stdout_callback( g_stdout_stream.str().c_str() );
118 }
119 // and clear buffer
120 g_stdout_stream.str( std::string() );
121
122 }
123}
124
125
126void ck_fflush_stderr()
127{
128 // check if stream contains a newline
129 if( g_stderr_stream.str().find( '\n' ) != std::string::npos )
130 {
131 // if so, print it
132 if( g_stderr_callback == NULL )
133 {
134 // send to stderr
135 fprintf( stderr, "%s", g_stderr_stream.str().c_str() );
136 }
137 else
138 {
139 // emit to callback
140 g_stderr_callback( g_stderr_stream.str().c_str() );
141 }
142
143 // and clear buffer
144 g_stderr_stream.str( std::string() );
145 }
146}
147
148
149void ck_vfprintf_stdout( const char * format, va_list args )
150{
151 // evaluate the format string
152 vsnprintf( g_buffer2, g_buffer2_size, format, args );
153
154 // send the formatted string to the buffer
155 g_stdout_stream << g_buffer2;
156
157 // try flushing
158 ck_fflush_stdout();
159}
160
161
162void ck_vfprintf_stderr( const char * format, va_list args )
163{
164 // evaluate the format string
165 vsnprintf( g_buffer2, g_buffer2_size, format, args );
166
167 // send the formatted string to the buffer
168 g_stderr_stream << g_buffer2;
169
170 // try flushing
171 ck_fflush_stderr();
172}
173
174
175
176void ck_set_stdout_callback( void (*callback)(const char *) )
177{
178 g_stdout_callback = callback;
179#ifdef __cplusplus
180 g_ck_stdoutstream.set_callback( callback );
181#endif
182}
183
184
185void ck_set_stderr_callback( void (*callback)(const char *) )
186{
187 g_stderr_callback = callback;
188#ifdef __cplusplus
189 g_ck_stderrstream.set_callback( callback );
190#endif
191}
192
193#ifdef __cplusplus
194extern "C++" {
195
196ChuckOutStream::ChuckOutStream( bool isErr )
197{
198 m_callback = NULL;
199 m_isErr = isErr;
200}
201
202
203ChuckOutStream::~ChuckOutStream()
204{
205}
206
207
208ChuckOutStream& ChuckOutStream::operator<<( const std::string val )
209{
210 m_stream << val;
211 if( val == CK_STDENDL )
212 {
213 this->flush();
214 }
215 return *this;
216}
217
218
219ChuckOutStream& ChuckOutStream::operator<<( const char * val )
220{
221 m_stream << val;
222 return *this;
223}
224
225
226ChuckOutStream& ChuckOutStream::operator<<( const double val )
227{
228 m_stream << val;
229 return *this;
230}
231
232
233ChuckOutStream& ChuckOutStream::operator<<( const float val )
234{
235 m_stream << val;
236 return *this;
237}
238
239
240ChuckOutStream& ChuckOutStream::operator<<( const unsigned long long val )
241{
242 m_stream << val;
243 return *this;
244}
245
246
247ChuckOutStream& ChuckOutStream::operator<<( const long long val )
248{
249 m_stream << val;
250 return *this;
251}
252
253
254ChuckOutStream& ChuckOutStream::operator<<( const unsigned long val )
255{
256 m_stream << val;
257 return *this;
258}
259
260
261ChuckOutStream& ChuckOutStream::operator<<( const long val )
262{
263 m_stream << val;
264 return *this;
265}
266
267
268ChuckOutStream& ChuckOutStream::operator<<( const unsigned int val )
269{
270 m_stream << val;
271 return *this;
272}
273
274
275ChuckOutStream& ChuckOutStream::operator<<( const int val )
276{
277 m_stream << val;
278 return *this;
279}
280
281
282ChuckOutStream& ChuckOutStream::operator<<( const bool val )
283{
284 m_stream << val;
285 return *this;
286}
287
288
289
290
291
292void ChuckOutStream::set_callback( void (*callback)( const char * ) )
293{
294 m_callback = callback;
295}
296
297
298void ChuckOutStream::flush()
299{
300 if( m_callback != NULL )
301 {
302 // send to callback
303 m_callback( m_stream.str().c_str() );
304 }
305 else
306 {
307 // print it
308 if( m_isErr )
309 {
310 // to cerr
311 std::cerr << m_stream.str().c_str();
312 std::cerr.flush();
313 }
314 else
315 {
316 // to cout
317 std::cout << m_stream.str().c_str();
318 std::cout.flush();
319 }
320 }
321 // clear buffer
322 m_stream.str( std::string() );
323}
324
325
326ChuckOutStream g_ck_stdoutstream( FALSE );
327ChuckOutStream g_ck_stderrstream( TRUE );
328
329}
330#endif
331
332
333
334
335// name
336static const char * g_str[] = {
337 "NONE", // 0
338 "CKCORE", // 1
339 "SYSTEM", // 2
340 "SEVERE", // 3
341 "WARN!!", // 4
342 "INFORM", // 5
343 "CONFIG", // 6
344 "FINE!!", // 7
345 "FINER!", // 8
346 "FINEST", // 9
347 "ALL!!" // 10
348};
349
350
351// intList
352typedef struct intList {int i; struct intList *rest;} *IntList;
353static IntList linePos=NULL;
354
355
356static int lastErrorCat(const char * str)
357{
358 assert(g_lasterrorIndex <= LASTERROR_SIZE-1);
359
360 size_t len = strlen(str);
361
362 strncat(g_lasterror, str, LASTERROR_SIZE-g_lasterrorIndex-1);
363
364 size_t appendCount = ck_min(LASTERROR_SIZE-g_lasterrorIndex-1, len);
365 g_lasterrorIndex += appendCount;
366
367 return appendCount > 0;
368}
369
370
371// constructor
372static IntList intList( int i, IntList rest )
373{
374 IntList l = (IntList)checked_malloc(sizeof *l);
375 l->i=i; l->rest=rest;
376 return l;
377}
378
379
380// new line in lexer
381void EM_newline(void)
382{
383 lineNum++;
384 EM_lineNum++;
385 EM_extLineNum++;
386 linePos = intList(EM_tokPos, linePos);
387}
388
389
390// content after rightmost '/'
391const char * mini( const char * str )
392{
393 int len = strlen( str );
394 const char * p = str + len;
395 while( p != str && *p != '/' && *p != '\\' ) p--;
396 return ( p == str || strlen(p+1) == 0 ? p : p+1 );
397}
398
399
400// content after 'struct'
401const char * mini_type( const char * str )
402{
403 if( !strncmp( str, "struct ", 7 ) ) str += 7;
404 const char * p = str;
405 while( *p && *p >= '0' && *p <= '9' ) p++;
406 return p;
407}
408
409void EM_reset_msg()
410{
411 g_lasterror[0] = '\0';
412 g_lasterrorIndex = 0;
413}
414
415// [%s]:line(%d).char(%d):
416void EM_error( int pos, const char * message, ... )
417{
418 va_list ap;
419 IntList lines = linePos;
420 int num = lineNum;
421
422 anyErrors = TRUE;
423 while( lines && lines->i >= pos )
424 {
425 lines = lines->rest;
426 num--;
427 }
428
429 // separate errmsgs with newlines
430 if( g_lasterror[0] != '\0' ) lastErrorCat( "\n" );
431
432 CK_FPRINTF_STDERR( "[%s]:", *fileName ? mini(fileName) : "chuck" );
433 sprintf( g_buffer, "[%s]:", *fileName ? mini(fileName) : "chuck" );
434 lastErrorCat( g_buffer );
435 if(lines)
436 {
437 CK_FPRINTF_STDERR( "line(%d).char(%d):", num, pos-lines->i );
438 sprintf( g_buffer, "line(%d).char(%d):", num, pos-lines->i );
439 lastErrorCat( g_buffer );
440 }
441 CK_FPRINTF_STDERR( " " );
442 lastErrorCat( " " );
443
444 va_start(ap, message);
445 CK_VFPRINTF_STDERR( message, ap);
446 va_end(ap);
447
448 va_start(ap, message);
449 vsprintf( g_buffer, message, ap );
450 va_end(ap);
451
452 CK_FPRINTF_STDERR( "\n");
453 CK_FFLUSH_STDERR();
454 lastErrorCat( g_buffer );
455}
456
457
458// [%s]:line(%d):
459void EM_error2( int line, const char * message, ... )
460{
461 va_list ap;
462
463 EM_extLineNum = line;
464
465 // separate errmsgs with newlines
466 if( g_lasterror[0] != '\0' ) lastErrorCat( "\n" );
467
468 CK_FPRINTF_STDERR( "[%s]:", *fileName ? mini(fileName) : "chuck" );
469 sprintf( g_buffer, "[%s]:", *fileName ? mini(fileName) : "chuck" );
470 lastErrorCat( g_buffer );
471 if(line)
472 {
473 CK_FPRINTF_STDERR( "line(%d):", line );
474 sprintf( g_buffer, "line(%d):", line );
475 lastErrorCat( g_buffer );
476 }
477 CK_FPRINTF_STDERR( " " );
478 lastErrorCat( " " );
479
480 va_start( ap, message );
481 CK_VFPRINTF_STDERR( message, ap );
482 va_end( ap );
483
484 va_start( ap, message );
485 vsprintf( g_buffer, message, ap );
486 va_end( ap );
487
488 lastErrorCat( g_buffer );
489 CK_FPRINTF_STDERR( "\n" );
490 CK_FFLUSH_STDERR();
491}
492
493
494// [%s]:line(%d):
495void EM_error2b( int line, const char * message, ... )
496{
497 va_list ap;
498
499 EM_extLineNum = line;
500
501 // separate errmsgs with newlines
502 if( g_lasterror[0] != '\0' ) lastErrorCat( "\n" );
503
504 CK_FPRINTF_STDERR( "[%s]:", *fileName ? mini(fileName) : "chuck" );
505 sprintf( g_buffer, "[%s]:", *fileName ? mini(fileName) : "chuck" );
506 lastErrorCat( g_buffer );
507 if(line)
508 {
509 CK_FPRINTF_STDERR( "line(%d):", line );
510 sprintf( g_buffer, "line(%d):", line );
511 lastErrorCat( g_buffer );
512 }
513 CK_FPRINTF_STDERR( " " );
514 lastErrorCat( " " );
515
516 va_start( ap, message );
517 CK_VFPRINTF_STDERR( message, ap );
518 va_end( ap );
519
520 va_start( ap, message );
521 vsprintf( g_buffer, message, ap );
522 va_end( ap );
523
524 lastErrorCat( g_buffer );
525 CK_FPRINTF_STDOUT( "\n" );
526 CK_FFLUSH_STDOUT();
527}
528
529
530//
531void EM_error3( const char * message, ... )
532{
533 va_list ap;
534
535 // separate errmsgs with newlines
536 if( g_lasterror[0] != '\0' ) lastErrorCat( "\n" );
537
538// g_lasterror[0] = '\0';
539 g_buffer[0] = '\0';
540
541 va_start( ap, message );
542 CK_VFPRINTF_STDERR( message, ap );
543 va_end( ap );
544
545 va_start( ap, message );
546 vsprintf( g_buffer, message, ap );
547 va_end( ap );
548
549 lastErrorCat( g_buffer );
550 CK_FPRINTF_STDERR( "\n" );
551 CK_FFLUSH_STDERR();
552}
553
554
555// log
556void EM_log( int level, const char * message, ... )
557{
558 va_list ap;
559
560 if( level > CK_LOG_CRAZY ) level = CK_LOG_CRAZY;
561 else if( level <= CK_LOG_NONE ) level = CK_LOG_NONE + 1;
562
563 // check level
564 if( level > g_loglevel ) return;
565
566 g_logmutex.acquire();
567 CK_FPRINTF_STDERR( "[chuck]:" );
568 CK_FPRINTF_STDERR( "(%i:%s): ", level, g_str[level] );
569
570 // if( g_logstack ) CK_FPRINTF_STDERR( " " );
571 for( int i = 0; i < g_logstack; i++ )
572 CK_FPRINTF_STDERR( " | " );
573
574 va_start( ap, message );
575 CK_VFPRINTF_STDERR( message, ap );
576 va_end( ap );
577
578 CK_FPRINTF_STDERR( "\n" );
579 CK_FFLUSH_STDERR();
580 g_logmutex.release();
581}
582
583
584// set log level
585void EM_setlog( int level )
586{
587 if( level > CK_LOG_CRAZY ) level = CK_LOG_CRAZY;
588 else if( level < CK_LOG_NONE ) level = CK_LOG_NONE;
589 g_loglevel = level;
590
591 // log this
592 EM_log( CK_LOG_SYSTEM, "setting log level to: %i (%s)...", level, g_str[level] );
593}
594
595// push log
596void EM_pushlog()
597{
598 g_logstack++;
599}
600
601// pop log
602void EM_poplog()
603{
604 g_logstack--;
605 if( g_logstack < 0 ) g_logstack = 0;
606}
607
608// prepare new file
609t_CKBOOL EM_reset( const char * fname, FILE * fd )
610{
611 anyErrors = FALSE;
612 fileName = fname ? fname : (c_str)"";
613 lineNum = 1;
614 EM_lineNum = 1;
615 EM_extLineNum = 1;
616
617 // free the intList
618 IntList curr = NULL;
619 while( linePos )
620 {
621 curr = linePos;
622 linePos = linePos->rest;
623 // free
624 free( curr );
625 }
626
627 // make new intList
628 linePos = intList( 0, NULL );
629
630 return TRUE;
631}
632
633
634// change file
635void EM_change_file( const char * fname )
636{
637 // set
638 fileName = fname ? fname : (c_str)"";
639 // more set
640 lineNum = 0;
641 EM_lineNum = 0;
642 EM_extLineNum = 0;
643}
644
645
646// return last error
647const char * EM_lasterror()
648{
649 return g_lasterror;
650}
core/chuck_errmsg.h+0−177
@@ -1,177 +0,0 @@
1/*----------------------------------------------------------------------------
2 ChucK Concurrent, On-the-fly Audio Programming Language
3 Compiler and Virtual Machine
4
5 Copyright (c) 2004 Ge Wang and Perry R. Cook. All rights reserved.
6 http://chuck.stanford.edu/
7 http://chuck.cs.princeton.edu/
8
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.
13
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.
18
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-----------------------------------------------------------------------------*/
24
25//-----------------------------------------------------------------------------
26// file: errmsg.h
27// desc: functions used in all phases of the compiler to give error messages
28// based on Andrew Appel's Tiger code
29//
30// author: Ge Wang (ge@ccrma.stanford.edu | gewang@cs.princeton.edu)
31// based on code by: Andrew Appel (appel@cs.princeton.edu)
32// date: Summer 2002
33//-----------------------------------------------------------------------------
34#ifndef __CHUCK_ERRORMSG_H__
35#define __CHUCK_ERRORMSG_H__
36
37#include "chuck_def.h"
38#include <stdio.h>
39
40
41#if defined(_cplusplus) || defined(__cplusplus)
42extern "C" {
43#endif
44
45
46extern t_CKBOOL EM_anyErrors;
47extern int EM_tokPos;
48extern int EM_lineNum;
49
50// EM_extLineNum is synced with EM_lineNum in lexer/parser phase, then synced
51// with scanner/typechecker (EM_lineNum is not synced with scanner/typechecker)
52extern int EM_extLineNum;
53
54void EM_newline( );
55
56// levels
57#define CK_LOG_CRAZY 10 // set this to log everything
58#define CK_LOG_FINEST 9
59#define CK_LOG_FINER 8
60#define CK_LOG_FINE 7
61#define CK_LOG_CONFIG 6
62#define CK_LOG_INFO 5
63#define CK_LOG_WARNING 4
64#define CK_LOG_SEVERE 3
65#define CK_LOG_SYSTEM 2
66#define CK_LOG_CORE 1
67#define CK_LOG_NONE 0 // set this to log nothing
68
69
70//-----------------------------------------------------------------------------
71// REFACTOR-2017: (jack) -- callback printing
72//-----------------------------------------------------------------------------
73// printing
74void ck_fprintf_stdout( const char * format, ... );
75void ck_fprintf_stderr( const char * format, ... );
76void ck_fflush_stdout();
77void ck_fflush_stderr();
78void ck_vfprintf_stdout( const char * format, va_list args );
79void ck_vfprintf_stderr( const char * format, va_list args );
80
81// callbacks
82void ck_set_stdout_callback( void (*callback)(const char *) );
83void ck_set_stderr_callback( void (*callback)(const char *) );
84
85#define CK_FPRINTF_STDOUT(...) ck_fprintf_stdout(__VA_ARGS__)
86#define CK_FPRINTF_STDERR(...) ck_fprintf_stderr(__VA_ARGS__)
87#define CK_FFLUSH_STDOUT() ck_fflush_stdout()
88#define CK_FFLUSH_STDERR() ck_fflush_stderr()
89#define CK_VFPRINTF_STDOUT(message, ap) ck_vfprintf_stdout(message, ap)
90#define CK_VFPRINTF_STDERR(message, ap) ck_vfprintf_stderr(message, ap)
91
92#ifdef __cplusplus
93// c++: custom stream-like thing
94extern "C++" {
95#include <sstream>
96
97class ChuckOutStream
98{
99public:
100 ChuckOutStream( bool isErr );
101 ~ChuckOutStream();
102
103 // there's probably a way to do this with templates or something
104 // this is not that way
105 ChuckOutStream& operator<<( const std::string val );
106 ChuckOutStream& operator<<( const char * val );
107 ChuckOutStream& operator<<( const double val );
108 ChuckOutStream& operator<<( const float val );
109 ChuckOutStream& operator<<( const unsigned long long val );
110 ChuckOutStream& operator<<( const long long val );
111 ChuckOutStream& operator<<( const unsigned long val );
112 ChuckOutStream& operator<<( const long val );
113 ChuckOutStream& operator<<( const unsigned int val );
114 ChuckOutStream& operator<<( const int val );
115 ChuckOutStream& operator<<( const bool val );
116
117 void set_callback( void (*callback)(const char *) );
118
119private:
120 void flush();
121 std::stringstream m_stream;
122 void (*m_callback)(const char *);
123 bool m_isErr;
124};
125
126
127extern ChuckOutStream g_ck_stdoutstream;
128extern ChuckOutStream g_ck_stderrstream;
129
130#define CK_STDCOUT g_ck_stdoutstream
131#define CK_STDCERR g_ck_stderrstream
132#define CK_STDENDL std::string("\n")
133
134}
135#else
136// c: oh well
137#define CK_STDCOUT std::cout
138#define CK_STDCERR std::cerr
139#define CK_STDENDL std::endl
140
141#endif
142//-----------------------------------------------------------------------------
143// here endeth the callback printing
144//-----------------------------------------------------------------------------
145
146
147
148
149void EM_log( int, c_constr, ... );
150void EM_setlog( int );
151void EM_pushlog();
152void EM_poplog();
153
154// actual level
155extern int g_loglevel;
156// macro to compare
157#define DO_LOG(x) ( x <= g_loglevel )
158
159void EM_error( int, c_constr, ... );
160void EM_error2( int, c_constr, ... );
161void EM_error2b( int, c_constr, ... );
162void EM_error3( c_constr, ... );
163void EM_impossible( c_constr, ... );
164t_CKBOOL EM_reset( c_constr filename, FILE * fd );
165void EM_change_file( c_constr filename );
166const char * EM_lasterror();
167void EM_reset_msg();
168
169const char * mini( const char * str );
170const char * mini_type( const char * str );
171
172#if defined(_cplusplus) || defined(__cplusplus)
173}
174#endif
175
176
177#endif
core/chuck_frame.cpp+0−165
@@ -1,165 +0,0 @@
1/*----------------------------------------------------------------------------
2 ChucK Concurrent, On-the-fly Audio Programming Language
3 Compiler and Virtual Machine
4
5 Copyright (c) 2004 Ge Wang and Perry R. Cook. All rights reserved.
6 http://chuck.stanford.edu/
7 http://chuck.cs.princeton.edu/
8
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.
13
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.
18
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-----------------------------------------------------------------------------*/
24
25//-----------------------------------------------------------------------------
26// file: chuck_frame.cpp
27// desc: chuck scope frame
28//
29// author: Ge Wang (ge@ccrma.stanford.edu | gewang@cs.princeton.edu)
30// date: Autumn 2002
31//-----------------------------------------------------------------------------
32#include "chuck_frame.h"
33using namespace std;
34
35
36
37
38//-----------------------------------------------------------------------------
39// name: Chuck_Frame()
40// desc: ...
41//-----------------------------------------------------------------------------
42Chuck_Frame::Chuck_Frame()
43{
44 // name
45 name = "";
46 // ofset
47 curr_offset = 0;
48 // don't know
49 num_access = 0;
50}
51
52
53
54
55//-----------------------------------------------------------------------------
56// name: alloc_local()
57// desc: ...
58//-----------------------------------------------------------------------------
59Chuck_Local * Chuck_Frame::alloc_local( t_CKUINT size, const string & name,
60 t_CKBOOL is_ref, t_CKBOOL is_obj, t_CKBOOL is_external )
61{
62 // alloc
63 Chuck_Local * local = new Chuck_Local;
64 // size
65 local->size = size;
66 // the offset
67 local->offset = this->curr_offset;
68 // ref
69 local->is_ref = is_ref;
70 // is object type? (added ge: 2012 april | added 1.3.0.0)
71 local->is_obj = is_obj;
72 // REFACTOR-2017: is external?
73 local->is_external = is_external;
74 // the next offset
75 this->curr_offset += local->size;
76 // name
77 local->name = name;
78 // push the local
79 this->stack.push_back( local );
80
81 return local;
82}
83
84
85
86
87//-----------------------------------------------------------------------------
88// name: push_scope()
89// desc: ...
90//-----------------------------------------------------------------------------
91void Chuck_Frame::push_scope( )
92{
93 stack.push_back( NULL );
94}
95
96
97
98
99//-----------------------------------------------------------------------------
100// name: get_scope()
101// desc: get current scope (added 1.3.0.0)
102//-----------------------------------------------------------------------------
103void Chuck_Frame::get_scope( vector<Chuck_Local *> & out ) const
104{
105 // sanity
106 assert( this->stack.size() > 0 );
107
108 // the local
109 Chuck_Local * local = NULL;
110 // the index
111 long index = this->stack.size() - 1;
112
113 // loop
114 while( index >= 0 && this->stack[index] != NULL )
115 {
116 // last thing
117 local = stack[index];
118 // move
119 index--;
120 // check if not null
121 if( local )
122 {
123 // copy out
124 out.push_back( local );
125 }
126 }
127}
128
129
130
131
132//-----------------------------------------------------------------------------
133// name: pop_scope()
134// desc: ....
135//-----------------------------------------------------------------------------
136void Chuck_Frame::pop_scope( vector<Chuck_Local *> & out )
137{
138 // sanity
139 assert( this->stack.size() > 0 );
140
141 // the local
142 Chuck_Local * local = NULL;
143
144 // loop
145 while( this->stack.size() && this->stack.back() )
146 {
147 // last thing
148 local = stack.back();
149 // pop
150 stack.pop_back();
151 // check if not null
152 if( local )
153 {
154 // offset
155 curr_offset -= local->size;
156 // copy out (NOTE: these locals should be memory managed outside)
157 out.push_back( local );
158 }
159 }
160
161 // sanity (should be at least one left)
162 assert( this->stack.size() > 0 );
163 // get ride of null boundary character (added 1.3.0.0)
164 this->stack.pop_back();
165}
core/chuck_frame.h+0−103
@@ -1,103 +0,0 @@
1/*----------------------------------------------------------------------------
2 ChucK Concurrent, On-the-fly Audio Programming Language
3 Compiler and Virtual Machine
4
5 Copyright (c) 2004 Ge Wang and Perry R. Cook. All rights reserved.
6 http://chuck.stanford.edu/
7 http://chuck.cs.princeton.edu/
8
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.
13
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.
18
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-----------------------------------------------------------------------------*/
24
25//-----------------------------------------------------------------------------
26// file: chuck_frame.h
27// desc: chuck scope frame
28//
29// author: Ge Wang (ge@ccrma.stanford.edu | gewang@cs.princeton.edu)
30// date: Autumn 2002
31//-----------------------------------------------------------------------------
32#ifndef __CHUCK_FRAME_H__
33#define __CHUCK_FRAME_H__
34
35#include "chuck_def.h"
36
37#include <string>
38#include <vector>
39
40
41//-----------------------------------------------------------------------------
42// name: struct Chuck_Local
43// desc: ...
44//-----------------------------------------------------------------------------
45struct Chuck_Local
46{
47 // name
48 std::string name;
49 // the size of the local
50 t_CKUINT size;
51 // is ref
52 t_CKBOOL is_ref;
53 // is an object type (added ge: 2012 april | added 1.3.0.0)
54 t_CKBOOL is_obj;
55 // REFACTOR-2017: is an external variable; external type
56 t_CKBOOL is_external;
57 // the offset
58 t_CKUINT offset;
59
60 // constructor
61 Chuck_Local()
62 // (added 1.3.0.0 -- is_obj)
63 { size = 0; is_ref = FALSE; is_obj = FALSE; is_external = FALSE; offset = 0; }
64};
65
66
67
68
69//-----------------------------------------------------------------------------
70// name: struct Chuck_Frame
71// desc: ...
72//-----------------------------------------------------------------------------
73struct Chuck_Frame
74{
75 // yes
76 std::string name;
77 // the offset
78 t_CKUINT curr_offset;
79 // not sure
80 t_CKUINT num_access;
81 // offset stack
82 std::vector<Chuck_Local *> stack;
83
84public:
85 Chuck_Frame();
86 ~Chuck_Frame() { }
87
88public:
89 // push scope
90 void push_scope();
91 // add local (added 1.3.0.0 -- is_obj)
92 Chuck_Local * alloc_local( t_CKUINT size, const std::string & name,
93 t_CKBOOL is_ref, t_CKBOOL is_obj, t_CKBOOL is_external );
94 // get the current scope (added 1.3.0.0)
95 void get_scope( std::vector<Chuck_Local *> & out ) const;
96 // pop scope
97 void pop_scope( std::vector<Chuck_Local *> & out );
98};
99
100
101
102
103#endif
core/chuck_instr.cpp+0−7490
@@ -1,7490 +0,0 @@
1/*----------------------------------------------------------------------------
2 ChucK Concurrent, On-the-fly Audio Programming Language
3 Compiler and Virtual Machine
4
5 Copyright (c) 2004 Ge Wang and Perry R. Cook. All rights reserved.
6 http://chuck.stanford.edu/
7 http://chuck.cs.princeton.edu/
8
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.
13
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.
18
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-----------------------------------------------------------------------------*/
24
25//-----------------------------------------------------------------------------
26// file: chuck_instr.cpp
27// desc: chuck virtual machine instruction set
28//
29// author: Ge Wang (ge@ccrma.stanford.edu | gewang@cs.princeton.edu)
30// date: Autumn 2002
31//-----------------------------------------------------------------------------
32#include <math.h>
33#include <limits.h>
34
35#include "chuck_type.h"
36#include "chuck_lang.h"
37#include "chuck_instr.h"
38#include "chuck_vm.h"
39#include "chuck_ugen.h"
40#include "chuck_dl.h"
41#include "chuck_errmsg.h"
42
43#include "util_string.h"
44
45#include <typeinfo>
46using namespace std;
47
48
49
50
51//-----------------------------------------------------------------------------
52// name: Chuck_Instr()
53// desc: base class constructor
54//-----------------------------------------------------------------------------
55Chuck_Instr::Chuck_Instr() {
56 // set linepos to 0 so we can tell later whether it has been set properly
57 m_linepos = 0;
58}
59
60
61
62
63//-----------------------------------------------------------------------------
64// name: name()
65// desc: ...
66//-----------------------------------------------------------------------------
67const char * Chuck_Instr::name() const
68{
69 return mini_type( typeid(*this).name() );
70}
71
72
73
74
75//-----------------------------------------------------------------------------
76// name: set_linepos()
77// desc: store line position for error messages
78//-----------------------------------------------------------------------------
79void Chuck_Instr::set_linepos(t_CKUINT linepos) {
80 m_linepos = linepos;
81}
82
83
84
85
86//-----------------------------------------------------------------------------
87// name: handle_overflow()
88// desc: stack overflow
89//-----------------------------------------------------------------------------
90static void handle_overflow( Chuck_VM_Shred * shred, Chuck_VM * vm )
91{
92 // we have a problem
93 CK_FPRINTF_STDERR(
94 "[chuck](VM): Exception StackOverflow in shred[id=%lu:%s], PC=[%lu]\n",
95 shred->xid, shred->name.c_str(), shred->pc );
96 // do something!
97 shred->is_running = FALSE;
98 shred->is_done = TRUE;
99}
100
101
102#pragma mark === Integer Arithmetic ===
103
104
105//-----------------------------------------------------------------------------
106// name: execute()
107// desc: ...
108//-----------------------------------------------------------------------------
109void Chuck_Instr_Add_int::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
110{
111 t_CKINT *& sp = (t_CKINT *&)shred->reg->sp;
112 pop_( sp, 2 );
113 push_( sp, val_(sp) + val_(sp+1) );
114}
115
116
117
118
119//-----------------------------------------------------------------------------
120// name: execute()
121// desc: ...
122//-----------------------------------------------------------------------------
123void Chuck_Instr_PreInc_int::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
124{
125 // t_CKBYTE *& mem_sp = (t_CKBYTE *&)shred->mem->sp;
126 t_CKINT **& reg_sp = (t_CKINT **&)shred->reg->sp;
127 t_CKINT *& the_sp = (t_CKINT *&)shred->reg->sp;
128
129 // pointer
130 pop_( reg_sp, 1 );
131 // increment value
132 (**(reg_sp))++;
133 // value on stack
134 push_( the_sp, **(reg_sp) );
135}
136
137
138
139
140//-----------------------------------------------------------------------------
141// name: execute()
142// desc: ...
143//-----------------------------------------------------------------------------
144void Chuck_Instr_PostInc_int::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
145{
146 // t_CKBYTE *& mem_sp = (t_CKBYTE *&)shred->mem->sp;
147 t_CKINT **& reg_sp = (t_CKINT **&)shred->reg->sp;
148 t_CKINT *& the_sp = (t_CKINT *&)shred->reg->sp;
149 t_CKINT * ptr;
150
151 // pointer
152 pop_( reg_sp, 1 );
153 // copy
154 ptr = *reg_sp;
155 // value on stack
156 push_( the_sp, **(reg_sp) );
157 // increment value
158 (*(ptr))++;
159}
160
161
162
163
164//-----------------------------------------------------------------------------
165// name: execute()
166// desc: ...
167//-----------------------------------------------------------------------------
168void Chuck_Instr_PreDec_int::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
169{
170 // t_CKBYTE *& mem_sp = (t_CKBYTE *&)shred->mem->sp;
171 t_CKINT **& reg_sp = (t_CKINT **&)shred->reg->sp;
172 t_CKINT *& the_sp = (t_CKINT *&)shred->reg->sp;
173
174 // pointer
175 pop_( reg_sp, 1 );
176 // decrement value
177 (**(reg_sp))--;
178 // value on stack
179 push_( the_sp, **(reg_sp) );
180}
181
182
183
184
185//-----------------------------------------------------------------------------
186// name: execute()
187// desc: ...
188//-----------------------------------------------------------------------------
189void Chuck_Instr_PostDec_int::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
190{
191 // t_CKBYTE *& mem_sp = (t_CKBYTE *&)shred->mem->sp;
192 t_CKINT **& reg_sp = (t_CKINT **&)shred->reg->sp;
193 t_CKINT *& the_sp = (t_CKINT *&)shred->reg->sp;
194 t_CKINT * ptr;
195
196 // pointer
197 pop_( reg_sp, 1 );
198 // copy
199 ptr = *reg_sp;
200 // value on stack
201 push_( the_sp, **(reg_sp) );
202 // decrement value
203 (*(ptr))--;
204}
205
206
207
208
209//-----------------------------------------------------------------------------
210// name: class Chuck_Instr_Dec_int_Addr
211// desc: ...
212//-----------------------------------------------------------------------------
213void Chuck_Instr_Dec_int_Addr::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
214{
215 // decrement value
216 (*((t_CKINT *)(m_val)))--;
217}
218
219
220
221
222//-----------------------------------------------------------------------------
223// name: exexute()
224// desc: ...
225//-----------------------------------------------------------------------------
226void Chuck_Instr_Complement_int::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
227{
228 t_CKINT *& sp = (t_CKINT *&)shred->reg->sp;
229 (*(sp-1)) = ~(*(sp-1));
230}
231
232
233
234
235//-----------------------------------------------------------------------------
236// name: execute()
237// desc: ...
238//-----------------------------------------------------------------------------
239void Chuck_Instr_Mod_int::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
240{
241 t_CKINT *& sp = (t_CKINT *&)shred->reg->sp;
242 pop_( sp, 2 );
243 push_( sp, val_(sp) % val_(sp+1) );
244}
245
246
247
248
249//-----------------------------------------------------------------------------
250// name: execute()
251// desc: ...
252//-----------------------------------------------------------------------------
253void Chuck_Instr_Mod_int_Reverse::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
254{
255 t_CKINT *& sp = (t_CKINT *&)shred->reg->sp;
256 pop_( sp, 2 );
257 push_( sp, val_(sp+1) % val_(sp) );
258}
259
260
261
262
263//-----------------------------------------------------------------------------
264// name: execute()
265// desc: ...
266//-----------------------------------------------------------------------------
267void Chuck_Instr_Minus_int::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
268{
269 t_CKINT *& sp = (t_CKINT *&)shred->reg->sp;
270 pop_( sp, 2 );
271 push_( sp, val_(sp) - val_(sp+1) );
272}
273
274
275
276
277//-----------------------------------------------------------------------------
278// name: execute()
279// desc: ...
280//-----------------------------------------------------------------------------
281void Chuck_Instr_Minus_int_Reverse::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
282{
283 t_CKINT *& sp = (t_CKINT *&)shred->reg->sp;
284 pop_( sp, 2 );
285 push_( sp, val_(sp+1) - val_(sp) );
286}
287
288
289
290
291//-----------------------------------------------------------------------------
292// name: execute()
293// desc: ...
294//-----------------------------------------------------------------------------
295void Chuck_Instr_Times_int::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
296{
297 t_CKINT *& sp = (t_CKINT *&)shred->reg->sp;
298 pop_( sp, 2 );
299 push_( sp, val_(sp) * val_(sp+1) );
300}
301
302
303
304
305//-----------------------------------------------------------------------------
306// name: execute()
307// desc: ...
308//-----------------------------------------------------------------------------
309void Chuck_Instr_Divide_int::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
310{
311 t_CKINT *& sp = (t_CKINT *&)shred->reg->sp;
312 pop_( sp, 2 );
313 if( val_(sp+1) == 0 ) goto div_zero;
314 push_( sp, val_(sp) / val_(sp+1) );
315
316 return;
317div_zero:
318 // we have a problem
319 CK_FPRINTF_STDERR(
320 "[chuck](VM): DivideByZeroException: on line[%lu] in shred[id=%lu:%s]\n",
321 m_linepos, shred->xid, shred->name.c_str());
322 goto done;
323
324done:
325 // do something!
326 shred->is_running = FALSE;
327 shred->is_done = TRUE;
328}
329
330
331
332
333//-----------------------------------------------------------------------------
334// name: execute()
335// desc: ...
336//-----------------------------------------------------------------------------
337void Chuck_Instr_Divide_int_Reverse::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
338{
339 t_CKINT *& sp = (t_CKINT *&)shred->reg->sp;
340 pop_( sp, 2 );
341 if( val_(sp) == 0 ) goto div_zero;
342 push_( sp, val_(sp+1) / val_(sp) );
343
344 return;
345div_zero:
346 // we have a problem
347 CK_FPRINTF_STDERR(
348 "[chuck](VM): DivideByZeroException: on line[%lu] in shred[id=%lu:%s]\n",
349 m_linepos, shred->xid, shred->name.c_str());
350 goto done;
351
352done:
353 // do something!
354 shred->is_running = FALSE;
355 shred->is_done = TRUE;
356}
357
358
359
360#pragma mark === Float Arithmetic ===
361
362
363//-----------------------------------------------------------------------------
364// name: execute()
365// desc: ...
366//-----------------------------------------------------------------------------
367void Chuck_Instr_Add_double::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
368{
369 t_CKFLOAT *& sp = (t_CKFLOAT *&)shred->reg->sp;
370 pop_( sp, 2 );
371 push_( sp, val_(sp) + val_(sp+1) );
372}
373
374
375
376
377//-----------------------------------------------------------------------------
378// name: execute()
379// desc: ...
380//-----------------------------------------------------------------------------
381void Chuck_Instr_Minus_double::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
382{
383 t_CKFLOAT *& sp = (t_CKFLOAT *&)shred->reg->sp;
384 pop_( sp, 2 );
385 push_( sp, val_(sp) - val_(sp+1) );
386}
387
388
389
390
391//-----------------------------------------------------------------------------
392// name: execute()
393// desc: ...
394//-----------------------------------------------------------------------------
395void Chuck_Instr_Minus_double_Reverse::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
396{
397 t_CKFLOAT *& sp = (t_CKFLOAT *&)shred->reg->sp;
398 pop_( sp, 2 );
399 push_( sp, val_(sp+1) - val_(sp) );
400}
401
402
403
404
405//-----------------------------------------------------------------------------
406// name: execute()
407// desc: ...
408//-----------------------------------------------------------------------------
409void Chuck_Instr_Times_double::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
410{
411 t_CKFLOAT *& sp = (t_CKFLOAT *&)shred->reg->sp;
412 pop_( sp, 2 );
413 push_( sp, val_(sp) * val_(sp+1) );
414}
415
416
417
418
419//-----------------------------------------------------------------------------
420// name: execute()
421// desc: ...
422//-----------------------------------------------------------------------------
423void Chuck_Instr_Divide_double::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
424{
425 t_CKFLOAT *& sp = (t_CKFLOAT *&)shred->reg->sp;
426 pop_( sp, 2 );
427 push_( sp, val_(sp) / val_(sp+1) );
428}
429
430
431
432
433
434//-----------------------------------------------------------------------------
435// name: execute()
436// desc: ...
437//-----------------------------------------------------------------------------
438void Chuck_Instr_Divide_double_Reverse::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
439{
440 t_CKFLOAT *& sp = (t_CKFLOAT *&)shred->reg->sp;
441 pop_( sp, 2 );
442 push_( sp, val_(sp+1) / val_(sp) );
443}
444
445
446
447
448//-----------------------------------------------------------------------------
449// name: execute()
450// desc: ...
451//-----------------------------------------------------------------------------
452void Chuck_Instr_Mod_double::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
453{
454 t_CKFLOAT *& sp = (t_CKFLOAT *&)shred->reg->sp;
455 pop_( sp, 2 );
456 push_( sp, ::fmod( val_(sp), val_(sp+1) ) );
457}
458
459
460
461
462//-----------------------------------------------------------------------------
463// name: execute()
464// desc: ...
465//-----------------------------------------------------------------------------
466void Chuck_Instr_Mod_double_Reverse::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
467{
468 t_CKFLOAT *& sp = (t_CKFLOAT *&)shred->reg->sp;
469 pop_( sp, 2 );
470 push_( sp, ::fmod( val_(sp+1), val_(sp) ) );
471}
472
473
474
475#pragma mark === Complex Arithmetic ===
476
477
478//-----------------------------------------------------------------------------
479// name: execute()
480// desc: ...
481//-----------------------------------------------------------------------------
482void Chuck_Instr_Add_complex::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
483{
484 t_CKCOMPLEX *& sp = (t_CKCOMPLEX *&)shred->reg->sp;
485 t_CKFLOAT *& sp_float = (t_CKFLOAT *&)sp;
486 t_CKFLOAT re, im;
487 pop_( sp, 2 );
488 re = sp->re + (sp+1)->re;
489 im = sp->im + (sp+1)->im;
490 push_( sp_float, re );
491 push_( sp_float, im );
492}
493
494
495
496
497//-----------------------------------------------------------------------------
498// name: execute()
499// desc: ...
500//-----------------------------------------------------------------------------
501void Chuck_Instr_Minus_complex::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
502{
503 t_CKCOMPLEX *& sp = (t_CKCOMPLEX *&)shred->reg->sp;
504 t_CKFLOAT *& sp_float = (t_CKFLOAT *&)sp;
505 t_CKFLOAT re, im;
506 pop_( sp, 2 );
507 re = sp->re - (sp+1)->re;
508 im = sp->im - (sp+1)->im;
509 push_( sp_float, re );
510 push_( sp_float, im );
511}
512
513
514
515
516//-----------------------------------------------------------------------------
517// name: execute()
518// desc: ...
519//-----------------------------------------------------------------------------
520void Chuck_Instr_Minus_complex_Reverse::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
521{
522 t_CKCOMPLEX *& sp = (t_CKCOMPLEX *&)shred->reg->sp;
523 t_CKFLOAT *& sp_float = (t_CKFLOAT *&)sp;
524 t_CKFLOAT re, im;
525 pop_( sp, 2 );
526 re = (sp+1)->re - sp->re;
527 im = (sp+1)->im - sp->im;
528 push_( sp_float, re );
529 push_( sp_float, im );
530}
531
532
533
534
535//-----------------------------------------------------------------------------
536// name: execute()
537// desc: ...
538//-----------------------------------------------------------------------------
539void Chuck_Instr_Times_complex::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
540{
541 t_CKCOMPLEX *& sp = (t_CKCOMPLEX *&)shred->reg->sp;
542 t_CKFLOAT *& sp_float = (t_CKFLOAT *&)sp;
543 t_CKFLOAT re, im;
544 pop_( sp, 2 );
545 re = sp->re * (sp+1)->re - sp->im * (sp+1)->im;
546 im = sp->re * (sp+1)->im + sp->im * (sp+1)->re;
547 push_( sp_float, re );
548 push_( sp_float, im );
549}
550
551
552
553
554//-----------------------------------------------------------------------------
555// name: execute()
556// desc: ...
557//-----------------------------------------------------------------------------
558void Chuck_Instr_Divide_complex::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
559{
560 t_CKCOMPLEX *& sp = (t_CKCOMPLEX *&)shred->reg->sp;
561 t_CKFLOAT *& sp_float = (t_CKFLOAT *&)sp;
562 t_CKFLOAT re, im, denom;
563
564 // pop
565 pop_( sp, 2 );
566 // complex division -> * complex conjugate of divisor
567 denom = (sp+1)->re*(sp+1)->re + (sp+1)->im*(sp+1)->im;
568 // go
569 re = sp->re*(sp+1)->re + sp->im*(sp+1)->im;
570 im = sp->im*(sp+1)->re - sp->re*(sp+1)->im;
571 // result
572 push_( sp_float, re/denom );
573 push_( sp_float, im/denom );
574}
575
576
577
578
579
580//-----------------------------------------------------------------------------
581// name: execute()
582// desc: ...
583//-----------------------------------------------------------------------------
584void Chuck_Instr_Divide_complex_Reverse::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
585{
586 t_CKCOMPLEX *& sp = (t_CKCOMPLEX *&)shred->reg->sp;
587 t_CKFLOAT *& sp_float = (t_CKFLOAT *&)sp;
588 t_CKFLOAT re, im, denom;
589
590 // pop
591 pop_( sp, 2 );
592 // complex division -> * complex conjugate of divisor
593 denom = sp->re*sp->re + sp->im*sp->im;
594 // go
595 re = sp->re*(sp+1)->re + sp->im*(sp+1)->im;
596 im = (sp+1)->im*sp->re - (sp+1)->re*sp->im;
597 // result
598 push_( sp_float, re/denom );
599 push_( sp_float, im/denom );
600}
601
602
603
604
605//-----------------------------------------------------------------------------
606// name: execute()
607// desc: ...
608//-----------------------------------------------------------------------------
609void Chuck_Instr_Add_polar::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
610{
611 t_CKPOLAR *& sp = (t_CKPOLAR *&)shred->reg->sp;
612 t_CKFLOAT *& sp_float = (t_CKFLOAT *&)sp;
613 t_CKCOMPLEX a, b;
614 pop_( sp, 2 );
615 a.re = sp->modulus * ::cos( sp->phase );
616 a.im = sp->modulus * ::sin( sp->phase );
617 b.re = (sp+1)->modulus * ::cos( (sp+1)->phase );
618 b.im = (sp+1)->modulus * ::sin( (sp+1)->phase );
619 a.re += b.re;
620 a.im += b.im;
621 push_( sp_float, ::hypot( a.re, a.im ) );
622 push_( sp_float, ::atan2( a.im, a.re ) );
623}
624
625
626
627
628//-----------------------------------------------------------------------------
629// name: execute()
630// desc: ...
631//-----------------------------------------------------------------------------
632void Chuck_Instr_Minus_polar::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
633{
634 t_CKPOLAR *& sp = (t_CKPOLAR *&)shred->reg->sp;
635 t_CKFLOAT *& sp_float = (t_CKFLOAT *&)sp;
636 t_CKCOMPLEX a, b;
637 pop_( sp, 2 );
638 a.re = sp->modulus * ::cos( sp->phase );
639 a.im = sp->modulus * ::sin( sp->phase );
640 b.re = (sp+1)->modulus * ::cos( (sp+1)->phase );
641 b.im = (sp+1)->modulus * ::sin( (sp+1)->phase );
642 a.re -= b.re;
643 a.im -= b.im;
644 push_( sp_float, ::hypot( a.re, a.im ) );
645 push_( sp_float, ::atan2( a.im, a.re ) );
646}
647
648
649
650
651//-----------------------------------------------------------------------------
652// name: execute()
653// desc: ...
654//-----------------------------------------------------------------------------
655void Chuck_Instr_Minus_polar_Reverse::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
656{
657 t_CKPOLAR *& sp = (t_CKPOLAR *&)shred->reg->sp;
658 t_CKFLOAT *& sp_float = (t_CKFLOAT *&)sp;
659 t_CKCOMPLEX a, b;
660 pop_( sp, 2 );
661 a.re = sp->modulus * ::cos( sp->phase );
662 a.im = sp->modulus * ::sin( sp->phase );
663 b.re = (sp+1)->modulus * ::cos( (sp+1)->phase );
664 b.im = (sp+1)->modulus * ::sin( (sp+1)->phase );
665 a.re = b.re - a.re;
666 a.im = b.im - a.im;
667 push_( sp_float, ::hypot( a.re, a.im ) );
668 push_( sp_float, ::atan2( a.im, a.re ) );
669}
670
671
672
673
674//-----------------------------------------------------------------------------
675// name: execute()
676// desc: ...
677//-----------------------------------------------------------------------------
678void Chuck_Instr_Times_polar::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
679{
680 t_CKPOLAR *& sp = (t_CKPOLAR *&)shred->reg->sp;
681 t_CKFLOAT *& sp_float = (t_CKFLOAT *&)sp;
682 t_CKFLOAT mag, phase;
683 pop_( sp, 2 );
684 mag = sp->modulus * (sp+1)->modulus;
685 phase = sp->phase + (sp+1)->phase;
686 push_( sp_float, mag );
687 push_( sp_float, phase );
688}
689
690
691
692
693//-----------------------------------------------------------------------------
694// name: execute()
695// desc: ...
696//-----------------------------------------------------------------------------
697void Chuck_Instr_Divide_polar::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
698{
699 t_CKPOLAR *& sp = (t_CKPOLAR *&)shred->reg->sp;
700 t_CKFLOAT *& sp_float = (t_CKFLOAT *&)sp;
701 t_CKFLOAT mag, phase;
702 pop_( sp, 2 );
703 mag = sp->modulus / (sp+1)->modulus;
704 phase = sp->phase - (sp+1)->phase;
705 push_( sp_float, mag );
706 push_( sp_float, phase );
707}
708
709
710
711
712
713//-----------------------------------------------------------------------------
714// name: execute()
715// desc: ...
716//-----------------------------------------------------------------------------
717void Chuck_Instr_Divide_polar_Reverse::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
718{
719 t_CKPOLAR *& sp = (t_CKPOLAR *&)shred->reg->sp;
720 t_CKFLOAT *& sp_float = (t_CKFLOAT *&)sp;
721 t_CKFLOAT mag, phase;
722 pop_( sp, 2 );
723 mag = (sp+1)->modulus / (sp)->modulus;
724 phase = (sp+1)->phase - sp->phase;
725 push_( sp_float, mag );
726 push_( sp_float, phase );
727}
728
729
730
731
732//-----------------------------------------------------------------------------
733// name: execute()
734// desc: add two vec3; ge: added 1.3.5.3 with other vec3 vec4 instructions
735//-----------------------------------------------------------------------------
736void Chuck_Instr_Add_vec3::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
737{
738 t_CKVEC3 *& sp = (t_CKVEC3 *&)shred->reg->sp;
739 t_CKFLOAT *& sp_float = (t_CKFLOAT *&)sp;
740 pop_( sp, 2 );
741 // result
742 t_CKVEC3 r;
743 r.x = sp->x + (sp+1)->x;
744 r.y = sp->y + (sp+1)->y;
745 r.z = sp->z + (sp+1)->z;
746 push_( sp_float, r.x );
747 push_( sp_float, r.y );
748 push_( sp_float, r.z );
749}
750
751
752
753
754//-----------------------------------------------------------------------------
755// name: execute()
756// desc: ...
757//-----------------------------------------------------------------------------
758void Chuck_Instr_Minus_vec3::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
759{
760 t_CKVEC3 *& sp = (t_CKVEC3 *&)shred->reg->sp;
761 t_CKFLOAT *& sp_float = (t_CKFLOAT *&)sp;
762 pop_( sp, 2 );
763 // result
764 t_CKVEC3 r;
765 r.x = sp->x - (sp+1)->x;
766 r.y = sp->y - (sp+1)->y;
767 r.z = sp->z - (sp+1)->z;
768 push_( sp_float, r.x );
769 push_( sp_float, r.y );
770 push_( sp_float, r.z );
771}
772
773
774
775
776//-----------------------------------------------------------------------------
777// name: execute()
778// desc: ...
779//-----------------------------------------------------------------------------
780void Chuck_Instr_XProduct_vec3::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
781{
782 t_CKVEC3 *& sp = (t_CKVEC3 *&)shred->reg->sp;
783 t_CKFLOAT *& sp_float = (t_CKFLOAT *&)sp;
784 pop_( sp, 2 );
785 // result
786 t_CKVEC3 result;
787 result.x = (sp->y * (sp+1)->z) - (sp->z * (sp+1)->y);
788 result.y = (sp->z * (sp+1)->x) - (sp->x * (sp+1)->z);
789 result.z = (sp->x * (sp+1)->y) - (sp->y * (sp+1)->x);
790 push_( sp_float, result.x );
791 push_( sp_float, result.y );
792 push_( sp_float, result.z );
793}
794
795
796
797
798//-----------------------------------------------------------------------------
799// name: execute()
800// desc: ...
801//-----------------------------------------------------------------------------
802void Chuck_Instr_float_Times_vec3::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
803{
804 // stack pointer
805 t_CKBYTE *& sp = (t_CKBYTE *&)shred->reg->sp;
806 // pointer number of bytes
807 pop_( sp, sz_FLOAT+sz_VEC3 );
808 // the float
809 t_CKFLOAT f = *((t_CKFLOAT *)sp);
810 // the vector
811 t_CKVEC3 v = *((t_CKVEC3 *)(sp+sz_FLOAT));
812 // result
813 t_CKVEC3 r;
814 r.x = v.x * f;
815 r.y = v.y * f;
816 r.z = v.z * f;
817 // pointer as vec3
818 t_CKVEC3 *& sp_vec3 = (t_CKVEC3 *&)sp;
819 // push on reg stack
820 push_( sp_vec3, r );
821}
822
823
824
825
826//-----------------------------------------------------------------------------
827// name: execute()
828// desc: ...
829//-----------------------------------------------------------------------------
830void Chuck_Instr_vec3_Times_float::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
831{
832 // stack pointer
833 t_CKBYTE *& sp = (t_CKBYTE *&)shred->reg->sp;
834 // pointer number of bytes
835 pop_( sp, sz_FLOAT+sz_VEC3 );
836 // the vector
837 t_CKVEC3 v = *((t_CKVEC3 *)sp);
838 // the float
839 t_CKFLOAT f = *((t_CKFLOAT *)(sp+sz_VEC3));
840 // result
841 t_CKVEC3 r;
842 r.x = v.x * f;
843 r.y = v.y * f;
844 r.z = v.z * f;
845 // pointer as vec3
846 t_CKVEC3 *& sp_vec3 = (t_CKVEC3 *&)sp;
847 // push on reg stack
848 push_( sp_vec3, r );
849}
850
851
852
853
854//-----------------------------------------------------------------------------
855// name: execute()
856// desc: ...
857//-----------------------------------------------------------------------------
858void Chuck_Instr_vec3_Divide_float::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
859{
860 // stack pointer
861 t_CKBYTE *& sp = (t_CKBYTE *&)shred->reg->sp;
862 // pointer number of bytes
863 pop_( sp, sz_FLOAT+sz_VEC3 );
864 // the vector
865 t_CKVEC3 v = *((t_CKVEC3 *)sp);
866 // the float
867 t_CKFLOAT f = *((t_CKFLOAT *)(sp+sz_VEC3));
868 // result
869 t_CKVEC3 r;
870 r.x = v.x / f;
871 r.y = v.y / f;
872 r.z = v.z / f;
873 // pointer as vec3
874 t_CKVEC3 *& sp_vec3 = (t_CKVEC3 *&)sp;
875 // push on reg stack
876 push_( sp_vec3, r );
877}
878
879
880
881
882//-----------------------------------------------------------------------------
883// name: execute()
884// desc: ...
885//-----------------------------------------------------------------------------
886void Chuck_Instr_Add_vec4::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
887{
888 t_CKVEC4 *& sp = (t_CKVEC4 *&)shred->reg->sp;
889 t_CKFLOAT *& sp_float = (t_CKFLOAT *&)sp;
890 pop_( sp, 2 );
891 // result
892 t_CKVEC4 r;
893 r.x = sp->x + (sp+1)->x;
894 r.y = sp->y + (sp+1)->y;
895 r.z = sp->z + (sp+1)->z;
896 r.w = sp->w + (sp+1)->w;
897 push_( sp_float, r.x );
898 push_( sp_float, r.y );
899 push_( sp_float, r.z );
900 push_( sp_float, r.w );
901}
902
903
904
905
906//-----------------------------------------------------------------------------
907// name: execute()
908// desc: ...
909//-----------------------------------------------------------------------------
910void Chuck_Instr_Minus_vec4::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
911{
912 t_CKVEC4 *& sp = (t_CKVEC4 *&)shred->reg->sp;
913 t_CKFLOAT *& sp_float = (t_CKFLOAT *&)sp;
914 pop_( sp, 2 );
915 // result
916 t_CKVEC4 r;
917 r.x = sp->x - (sp+1)->x;
918 r.y = sp->y - (sp+1)->y;
919 r.z = sp->z - (sp+1)->z;
920 r.w = sp->w - (sp+1)->w;
921 push_( sp_float, r.x );
922 push_( sp_float, r.y );
923 push_( sp_float, r.z );
924 push_( sp_float, r.w );
925}
926
927
928
929
930//-----------------------------------------------------------------------------
931// name: execute()
932// desc: ...
933//-----------------------------------------------------------------------------
934void Chuck_Instr_XProduct_vec4::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
935{
936 t_CKVEC4 *& sp = (t_CKVEC4 *&)shred->reg->sp;
937 t_CKFLOAT *& sp_float = (t_CKFLOAT *&)sp;
938 pop_( sp, 2 );
939 // result
940 t_CKVEC4 result;
941 result.x = (sp->y * (sp+1)->z) - (sp->z * (sp+1)->y);
942 result.y = (sp->z * (sp+1)->x) - (sp->x * (sp+1)->z);
943 result.z = (sp->x * (sp+1)->y) - (sp->y * (sp+1)->x);
944 result.w = 0;
945 push_( sp_float, result.x );
946 push_( sp_float, result.y );
947 push_( sp_float, result.z );
948 push_( sp_float, result.w );
949}
950
951
952
953
954//-----------------------------------------------------------------------------
955// name: execute()
956// desc: ...
957//-----------------------------------------------------------------------------
958void Chuck_Instr_float_Times_vec4::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
959{
960 // stack pointer
961 t_CKBYTE *& sp = (t_CKBYTE *&)shred->reg->sp;
962 // pointer number of bytes
963 pop_( sp, sz_FLOAT+sz_VEC4 );
964 // the float
965 t_CKFLOAT f = *((t_CKFLOAT *)sp);
966 // the vector
967 t_CKVEC4 v = *((t_CKVEC4 *)(sp+sz_FLOAT));
968 // result
969 t_CKVEC4 r;
970 r.x = v.x * f;
971 r.y = v.y * f;
972 r.z = v.z * f;
973 r.w = v.w * f;
974 // pointer as vec4
975 t_CKVEC4 *& sp_vec4 = (t_CKVEC4 *&)sp;
976 // push on reg stack
977 push_( sp_vec4, r );
978}
979
980
981
982
983//-----------------------------------------------------------------------------
984// name: execute()
985// desc: ...
986//-----------------------------------------------------------------------------
987void Chuck_Instr_vec4_Times_float::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
988{
989 // stack pointer
990 t_CKBYTE *& sp = (t_CKBYTE *&)shred->reg->sp;
991 // pointer number of bytes
992 pop_( sp, sz_FLOAT+sz_VEC4 );
993 // the vector
994 t_CKVEC4 v = *((t_CKVEC4 *)sp);
995 // the float
996 t_CKFLOAT f = *((t_CKFLOAT *)(sp+sz_VEC4));
997 // result
998 t_CKVEC4 r;
999 r.x = v.x * f;
1000 r.y = v.y * f;
1001 r.z = v.z * f;
1002 r.w = v.w * f;
1003 // pointer as vec4
1004 t_CKVEC4 *& sp_vec4 = (t_CKVEC4 *&)sp;
1005 // push on reg stack
1006 push_( sp_vec4, r );
1007}
1008
1009
1010
1011
1012//-----------------------------------------------------------------------------
1013// name: execute()
1014// desc: ...
1015//-----------------------------------------------------------------------------
1016void Chuck_Instr_vec4_Divide_float::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
1017{
1018 // stack pointer
1019 t_CKBYTE *& sp = (t_CKBYTE *&)shred->reg->sp;
1020 // pointer number of bytes
1021 pop_( sp, sz_FLOAT+sz_VEC4 );
1022 // the vector
1023 t_CKVEC4 v = *((t_CKVEC4 *)sp);
1024 // the float
1025 t_CKFLOAT f = *((t_CKFLOAT *)(sp+sz_VEC4));
1026 // result
1027 t_CKVEC4 r;
1028 r.x = v.x / f;
1029 r.y = v.y / f;
1030 r.z = v.z / f;
1031 r.w = v.w / f;
1032 // pointer as vec4
1033 t_CKVEC4 *& sp_vec4 = (t_CKVEC4 *&)sp;
1034 // push on reg stack
1035 push_( sp_vec4, r );
1036}
1037
1038
1039
1040
1041#pragma mark === Arithmetic Assignment ===
1042
1043
1044//-----------------------------------------------------------------------------
1045// name: execute()
1046// desc: ...
1047//-----------------------------------------------------------------------------
1048void Chuck_Instr_Add_int_Assign::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
1049{
1050 t_CKINT temp, *& sp = (t_CKINT *&)shred->reg->sp;
1051 pop_( sp, 2 );
1052 temp = **(t_CKINT **)(sp+1) += val_(sp);
1053 push_( sp, temp );
1054}
1055
1056
1057
1058
1059//-----------------------------------------------------------------------------
1060// name: execute()
1061// desc: ...
1062//-----------------------------------------------------------------------------
1063void Chuck_Instr_Mod_int_Assign::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
1064{
1065 t_CKINT temp, *& sp = (t_CKINT *&)shred->reg->sp;
1066 pop_( sp, 2 );
1067 temp = **(t_CKINT **)(sp+1) %= val_(sp);
1068 push_( sp, temp );
1069}
1070
1071
1072
1073
1074//-----------------------------------------------------------------------------
1075// name: execute()
1076// desc: ...
1077//-----------------------------------------------------------------------------
1078void Chuck_Instr_Minus_int_Assign::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
1079{
1080 t_CKINT temp, *& sp = (t_CKINT *&)shred->reg->sp;
1081 pop_( sp, 2 );
1082 temp = **(t_CKINT **)(sp+1) -= val_(sp);
1083 push_( sp, temp );
1084}
1085
1086
1087
1088
1089//-----------------------------------------------------------------------------
1090// name: execute()
1091// desc: ...
1092//-----------------------------------------------------------------------------
1093void Chuck_Instr_Times_int_Assign::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
1094{
1095 t_CKINT temp, *& sp = (t_CKINT *&)shred->reg->sp;
1096 pop_( sp, 2 );
1097 temp = **(t_CKINT **)(sp+1) *= val_(sp);
1098 push_( sp, temp );
1099}
1100
1101
1102
1103
1104//-----------------------------------------------------------------------------
1105// name: execute()
1106// desc: ...
1107//-----------------------------------------------------------------------------
1108void Chuck_Instr_Divide_int_Assign::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
1109{
1110 t_CKINT temp, *& sp = (t_CKINT *&)shred->reg->sp;
1111 pop_( sp, 2 );
1112 if( val_(sp) == 0 ) goto div_zero;
1113 temp = **(t_CKINT **)(sp+1) /= val_(sp);
1114 push_( sp, temp );
1115
1116 return;
1117div_zero:
1118 // we have a problem
1119 CK_FPRINTF_STDERR(
1120 "[chuck](VM): DivideByZeroException: on line[%lu] in shred[id=%lu:%s]\n",
1121 m_linepos, shred->xid, shred->name.c_str());
1122 goto done;
1123
1124done:
1125 // do something!
1126 shred->is_running = FALSE;
1127 shred->is_done = TRUE;
1128}
1129
1130
1131
1132//-----------------------------------------------------------------------------
1133// name: execute()
1134// desc: ...
1135//-----------------------------------------------------------------------------
1136void Chuck_Instr_Add_double_Assign::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
1137{
1138 t_CKFLOAT temp;
1139 t_CKBYTE *& sp = (t_CKBYTE *&)shred->reg->sp;
1140 // pop value + pointer
1141 pop_( sp, sz_FLOAT + sz_UINT );
1142 // assign
1143 temp = **(t_CKFLOAT **)(sp+sz_FLOAT) += val_((t_CKFLOAT *&)sp);
1144 // push result
1145 push_( (t_CKFLOAT *&)sp, temp );
1146}
1147
1148
1149
1150
1151//-----------------------------------------------------------------------------
1152// name: execute()
1153// desc: ...
1154//-----------------------------------------------------------------------------
1155void Chuck_Instr_Minus_double_Assign::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
1156{
1157 t_CKFLOAT temp;
1158 t_CKBYTE *& sp = (t_CKBYTE *&)shred->reg->sp;
1159 // pop value + pointer
1160 pop_( sp, sz_FLOAT + sz_UINT );
1161 // assign
1162 temp = **(t_CKFLOAT **)(sp+sz_FLOAT) -= val_((t_CKFLOAT *&)sp);
1163 // push result
1164 push_( (t_CKFLOAT *&)sp, temp );
1165}
1166
1167
1168
1169
1170//-----------------------------------------------------------------------------
1171// name: execute()
1172// desc: ...
1173//-----------------------------------------------------------------------------
1174void Chuck_Instr_Times_double_Assign::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
1175{
1176 t_CKFLOAT temp;
1177 t_CKBYTE *& sp = (t_CKBYTE *&)shred->reg->sp;
1178 // pop value + pointer
1179 pop_( sp, sz_FLOAT + sz_UINT );
1180 // assign
1181 temp = **(t_CKFLOAT **)(sp+sz_FLOAT) *= val_((t_CKFLOAT *&)sp);
1182 // push result
1183 push_( (t_CKFLOAT *&)sp, temp );
1184}
1185
1186
1187
1188
1189//-----------------------------------------------------------------------------
1190// name: execute()
1191// desc: ...
1192//-----------------------------------------------------------------------------
1193void Chuck_Instr_Divide_double_Assign::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
1194{
1195 t_CKFLOAT temp;
1196 t_CKBYTE *& sp = (t_CKBYTE *&)shred->reg->sp;
1197 // pop value + pointer
1198 pop_( sp, sz_FLOAT + sz_UINT );
1199 // assign
1200 temp = **(t_CKFLOAT **)(sp+sz_FLOAT) /= val_((t_CKFLOAT *&)sp);
1201 // push result
1202 push_( (t_CKFLOAT *&)sp, temp );
1203}
1204
1205
1206
1207
1208//-----------------------------------------------------------------------------
1209// name: execute()
1210// desc: ...
1211//-----------------------------------------------------------------------------
1212void Chuck_Instr_Mod_double_Assign::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
1213{
1214 t_CKFLOAT temp;
1215 t_CKBYTE *& sp = (t_CKBYTE *&)shred->reg->sp;
1216 // pop value + pointer
1217 pop_( sp, sz_FLOAT + sz_UINT );
1218 // assign
1219 temp = ::fmod( **(t_CKFLOAT **)(sp+sz_FLOAT), val_((t_CKFLOAT *&)sp) );
1220 **(t_CKFLOAT **)(sp+sz_FLOAT) = temp;
1221 // push result
1222 push_( (t_CKFLOAT *&)sp, temp );
1223}
1224
1225
1226
1227
1228//-----------------------------------------------------------------------------
1229// name: execute()
1230// desc: ...
1231//-----------------------------------------------------------------------------
1232void Chuck_Instr_Add_complex_Assign::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
1233{
1234 t_CKBYTE *& sp = (t_CKBYTE *&)shred->reg->sp;
1235 t_CKCOMPLEX temp;
1236 // pop value + pointer
1237 pop_( sp, sz_COMPLEX + sz_UINT );
1238
1239 // assign
1240 temp.re = (*(t_CKCOMPLEX **)(sp+sz_COMPLEX))->re += ((t_CKCOMPLEX *&)sp)->re;
1241 temp.im = (*(t_CKCOMPLEX **)(sp+sz_COMPLEX))->im += ((t_CKCOMPLEX *&)sp)->im;
1242 // push result
1243 push_( (t_CKCOMPLEX *&)sp, temp );
1244}
1245
1246
1247
1248
1249//-----------------------------------------------------------------------------
1250// name: execute()
1251// desc: ...
1252//-----------------------------------------------------------------------------
1253void Chuck_Instr_Minus_complex_Assign::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
1254{
1255 t_CKBYTE *& sp = (t_CKBYTE *&)shred->reg->sp;
1256 t_CKCOMPLEX temp;
1257 // pop value + pointer
1258 pop_( sp, sz_COMPLEX + sz_UINT );
1259
1260 // assign
1261 temp.re = (*(t_CKCOMPLEX **)(sp+sz_COMPLEX))->re -= ((t_CKCOMPLEX *&)sp)->re;
1262 temp.im = (*(t_CKCOMPLEX **)(sp+sz_COMPLEX))->im -= ((t_CKCOMPLEX *&)sp)->im;
1263 // push result
1264 push_( (t_CKCOMPLEX *&)sp, temp );
1265}
1266
1267
1268
1269
1270//-----------------------------------------------------------------------------
1271// name: execute()
1272// desc: ...
1273//-----------------------------------------------------------------------------
1274void Chuck_Instr_Times_complex_Assign::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
1275{
1276 t_CKBYTE *& sp = (t_CKBYTE *&)shred->reg->sp;
1277 t_CKCOMPLEX temp, a, b;
1278 // pop value + pointer
1279 pop_( sp, sz_COMPLEX + sz_UINT );
1280 // copy
1281 a = **(t_CKCOMPLEX **)(sp+sz_COMPLEX);
1282 b = *(t_CKCOMPLEX *&)sp;
1283 // calculate
1284 temp.re = a.re * b.re - a.im * b.im;
1285 temp.im = a.re * b.im + a.im * b.re;
1286 // assign
1287 (*(t_CKCOMPLEX **)(sp+sz_COMPLEX))->re = temp.re;
1288 (*(t_CKCOMPLEX **)(sp+sz_COMPLEX))->im = temp.im;
1289 // push result
1290 push_( (t_CKCOMPLEX *&)sp, temp );
1291}
1292
1293
1294
1295
1296//-----------------------------------------------------------------------------
1297// name: execute()
1298// desc: ...
1299//-----------------------------------------------------------------------------
1300void Chuck_Instr_Divide_complex_Assign::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
1301{
1302 t_CKBYTE *& sp = (t_CKBYTE *&)shred->reg->sp;
1303 t_CKCOMPLEX temp, a, b;
1304 t_CKFLOAT denom;
1305 // pop value + pointer
1306 pop_( sp, sz_COMPLEX + sz_UINT );
1307 // copy
1308 a = **(t_CKCOMPLEX **)(sp+sz_COMPLEX);
1309 b = *(t_CKCOMPLEX *&)sp;
1310 // calculate
1311 temp.re = a.re * b.re + a.im * b.im;
1312 temp.im = a.im * b.re - a.re * b.im;
1313 denom = b.re * b.re + b.im * b.im;
1314 temp.re /= denom;
1315 temp.im /= denom;
1316 // assign
1317 (*(t_CKCOMPLEX **)(sp+sz_COMPLEX))->re = temp.re;
1318 (*(t_CKCOMPLEX **)(sp+sz_COMPLEX))->im = temp.im;
1319 // push result
1320 push_( (t_CKCOMPLEX *&)sp, temp );
1321}
1322
1323
1324
1325
1326//-----------------------------------------------------------------------------
1327// name: execute()
1328// desc: ...
1329//-----------------------------------------------------------------------------
1330void Chuck_Instr_Add_polar_Assign::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
1331{
1332 t_CKBYTE *& sp = (t_CKBYTE *&)shred->reg->sp;
1333 t_CKPOLAR result, * pa, * pb;
1334 t_CKCOMPLEX temp, a, b;
1335 // pop value + pointer
1336 pop_( sp, sz_POLAR + sz_UINT );
1337 // pointer copy
1338 pa = *(t_CKPOLAR **)(sp+sz_POLAR);
1339 pb = (t_CKPOLAR *&)sp;
1340 // rectangular
1341 a.re = pa->modulus * ::cos(pa->phase);
1342 a.im = pa->modulus * ::sin(pa->phase);
1343 b.re = pb->modulus * ::cos(pb->phase);
1344 b.im = pb->modulus * ::sin(pb->phase);
1345 // calculate
1346 temp.re = a.re + b.re;
1347 temp.im = a.im + b.im;
1348 // assign
1349 result.modulus = (*(t_CKPOLAR **)(sp+sz_POLAR))->modulus = ::hypot(temp.re,temp.im);
1350 result.phase = (*(t_CKPOLAR **)(sp+sz_POLAR))->phase = ::atan2(temp.im,temp.re);
1351 // push result
1352 push_( (t_CKPOLAR *&)sp, result );
1353}
1354
1355
1356
1357
1358//-----------------------------------------------------------------------------
1359// name: execute()
1360// desc: ...
1361//-----------------------------------------------------------------------------
1362void Chuck_Instr_Minus_polar_Assign::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
1363{
1364 t_CKBYTE *& sp = (t_CKBYTE *&)shred->reg->sp;
1365 t_CKPOLAR result, * pa, * pb;
1366 t_CKCOMPLEX temp, a, b;
1367 // pop value + pointer
1368 pop_( sp, sz_POLAR + sz_UINT );
1369 // pointer copy
1370 pa = *(t_CKPOLAR **)(sp+sz_POLAR);
1371 pb = (t_CKPOLAR *&)sp;
1372 // rectangular
1373 a.re = pa->modulus * ::cos(pa->phase);
1374 a.im = pa->modulus * ::sin(pa->phase);
1375 b.re = pb->modulus * ::cos(pb->phase);
1376 b.im = pb->modulus * ::sin(pb->phase);
1377 // calculate
1378 temp.re = a.re - b.re;
1379 temp.im = a.im - b.im;
1380 // assign
1381 result.modulus = (*(t_CKPOLAR **)(sp+sz_POLAR))->modulus = ::hypot(temp.re,temp.im);
1382 result.phase = (*(t_CKPOLAR **)(sp+sz_POLAR))->phase = ::atan2(temp.im,temp.re);
1383 // push result
1384 push_( (t_CKPOLAR *&)sp, result );
1385}
1386
1387
1388
1389
1390//-----------------------------------------------------------------------------
1391// name: execute()
1392// desc: ...
1393//-----------------------------------------------------------------------------
1394void Chuck_Instr_Times_polar_Assign::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
1395{
1396 t_CKBYTE *& sp = (t_CKBYTE *&)shred->reg->sp;
1397 t_CKPOLAR temp;
1398 // pop value + pointer
1399 pop_( sp, sz_POLAR + sz_UINT );
1400
1401 // assign
1402 temp.modulus = (*(t_CKPOLAR **)(sp+sz_POLAR))->modulus *= ((t_CKPOLAR *&)sp)->modulus;
1403 temp.phase = (*(t_CKPOLAR **)(sp+sz_POLAR))->phase += ((t_CKPOLAR *&)sp)->phase;
1404 // push result
1405 push_( (t_CKPOLAR *&)sp, temp );
1406}
1407
1408
1409
1410
1411//-----------------------------------------------------------------------------
1412// name: execute()
1413// desc: ...
1414//-----------------------------------------------------------------------------
1415void Chuck_Instr_Divide_polar_Assign::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
1416{
1417 t_CKBYTE *& sp = (t_CKBYTE *&)shred->reg->sp;
1418 t_CKPOLAR temp;
1419 // pop value + pointer
1420 pop_( sp, sz_POLAR + sz_UINT );
1421
1422 // assign
1423 temp.modulus = (*(t_CKPOLAR **)(sp+sz_POLAR))->modulus /= ((t_CKPOLAR *&)sp)->modulus;
1424 temp.phase = (*(t_CKPOLAR **)(sp+sz_POLAR))->phase -= ((t_CKPOLAR *&)sp)->phase;
1425 // push result
1426 push_( (t_CKPOLAR *&)sp, temp );
1427}
1428
1429
1430
1431
1432//-----------------------------------------------------------------------------
1433// name: execute()
1434// desc: ...
1435//-----------------------------------------------------------------------------
1436void Chuck_Instr_Add_vec3_Assign::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
1437{
1438 t_CKBYTE *& sp = (t_CKBYTE *&)shred->reg->sp;
1439 t_CKVEC3 temp;
1440 // pop value + pointer
1441 pop_( sp, sz_VEC3 + sz_UINT );
1442
1443 // assign
1444 temp.x = (*(t_CKVEC3 **)(sp+sz_VEC3))->x += ((t_CKVEC3 *&)sp)->x;
1445 temp.y = (*(t_CKVEC3 **)(sp+sz_VEC3))->y += ((t_CKVEC3 *&)sp)->y;
1446 temp.z = (*(t_CKVEC3 **)(sp+sz_VEC3))->z += ((t_CKVEC3 *&)sp)->z;
1447 // push result
1448 push_( (t_CKVEC3 *&)sp, temp );
1449}
1450
1451
1452
1453
1454//-----------------------------------------------------------------------------
1455// name: execute()
1456// desc: ...
1457//-----------------------------------------------------------------------------
1458void Chuck_Instr_Minus_vec3_Assign::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
1459{
1460 t_CKBYTE *& sp = (t_CKBYTE *&)shred->reg->sp;
1461 t_CKVEC3 temp;
1462 // pop value + pointer
1463 pop_( sp, sz_VEC3 + sz_UINT );
1464
1465 // assign
1466 temp.x = (*(t_CKVEC3 **)(sp+sz_VEC3))->x -= ((t_CKVEC3 *&)sp)->x;
1467 temp.y = (*(t_CKVEC3 **)(sp+sz_VEC3))->y -= ((t_CKVEC3 *&)sp)->y;
1468 temp.z = (*(t_CKVEC3 **)(sp+sz_VEC3))->z -= ((t_CKVEC3 *&)sp)->z;
1469 // push result
1470 push_( (t_CKVEC3 *&)sp, temp );
1471}
1472
1473
1474
1475
1476//-----------------------------------------------------------------------------
1477// name: execute()
1478// desc: ...
1479//-----------------------------------------------------------------------------
1480void Chuck_Instr_float_Times_vec3_Assign::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
1481{
1482 t_CKBYTE *& sp = (t_CKBYTE *&)shred->reg->sp;
1483 t_CKVEC3 temp;
1484 // pop float + pointer
1485 pop_( sp, sz_FLOAT + sz_UINT );
1486
1487 // assign
1488 temp.x = (*(t_CKVEC3 **)(sp+sz_FLOAT))->x *= *((t_CKFLOAT *)sp);
1489 temp.y = (*(t_CKVEC3 **)(sp+sz_FLOAT))->y *= *((t_CKFLOAT *)sp);
1490 temp.z = (*(t_CKVEC3 **)(sp+sz_FLOAT))->z *= *((t_CKFLOAT *)sp);
1491 // push result
1492 push_( (t_CKVEC3 *&)sp, temp );
1493}
1494
1495
1496
1497
1498//-----------------------------------------------------------------------------
1499// name: execute()
1500// desc: ...
1501//-----------------------------------------------------------------------------
1502void Chuck_Instr_vec3_Divide_float_Assign::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
1503{
1504 t_CKBYTE *& sp = (t_CKBYTE *&)shred->reg->sp;
1505 t_CKVEC3 temp;
1506 // pop float + pointer
1507 pop_( sp, sz_FLOAT + sz_UINT );
1508
1509 // assign
1510 temp.x = (*(t_CKVEC3 **)(sp+sz_FLOAT))->x /= *((t_CKFLOAT *)sp);
1511 temp.y = (*(t_CKVEC3 **)(sp+sz_FLOAT))->y /= *((t_CKFLOAT *)sp);
1512 temp.z = (*(t_CKVEC3 **)(sp+sz_FLOAT))->z /= *((t_CKFLOAT *)sp);
1513 // push result
1514 push_( (t_CKVEC3 *&)sp, temp );
1515}
1516
1517
1518
1519
1520//-----------------------------------------------------------------------------
1521// name: execute()
1522// desc: ...
1523//-----------------------------------------------------------------------------
1524void Chuck_Instr_Add_vec4_Assign::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
1525{
1526 t_CKBYTE *& sp = (t_CKBYTE *&)shred->reg->sp;
1527 t_CKVEC4 temp;
1528 // pop value + pointer
1529 pop_( sp, sz_VEC4 + sz_UINT );
1530
1531 // assign
1532 temp.x = (*(t_CKVEC4 **)(sp+sz_VEC4))->x += ((t_CKVEC4 *&)sp)->x;
1533 temp.y = (*(t_CKVEC4 **)(sp+sz_VEC4))->y += ((t_CKVEC4 *&)sp)->y;
1534 temp.z = (*(t_CKVEC4 **)(sp+sz_VEC4))->z += ((t_CKVEC4 *&)sp)->z;
1535 temp.w = (*(t_CKVEC4 **)(sp+sz_VEC4))->w += ((t_CKVEC4 *&)sp)->w;
1536 // push result
1537 push_( (t_CKVEC4 *&)sp, temp );
1538}
1539
1540
1541
1542
1543//-----------------------------------------------------------------------------
1544// name: execute()
1545// desc: ...
1546//-----------------------------------------------------------------------------
1547void Chuck_Instr_Minus_vec4_Assign::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
1548{
1549 t_CKBYTE *& sp = (t_CKBYTE *&)shred->reg->sp;
1550 t_CKVEC4 temp;
1551 // pop value + pointer
1552 pop_( sp, sz_VEC4 + sz_UINT );
1553
1554 // assign
1555 temp.x = (*(t_CKVEC4 **)(sp+sz_VEC4))->x -= ((t_CKVEC4 *&)sp)->x;
1556 temp.y = (*(t_CKVEC4 **)(sp+sz_VEC4))->y -= ((t_CKVEC4 *&)sp)->y;
1557 temp.z = (*(t_CKVEC4 **)(sp+sz_VEC4))->z -= ((t_CKVEC4 *&)sp)->z;
1558 temp.w = (*(t_CKVEC4 **)(sp+sz_VEC4))->w -= ((t_CKVEC4 *&)sp)->w;
1559 // push result
1560 push_( (t_CKVEC4 *&)sp, temp );
1561}
1562
1563
1564
1565
1566//-----------------------------------------------------------------------------
1567// name: execute()
1568// desc: ...
1569//-----------------------------------------------------------------------------
1570void Chuck_Instr_float_Times_vec4_Assign::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
1571{
1572 t_CKBYTE *& sp = (t_CKBYTE *&)shred->reg->sp;
1573 t_CKVEC4 temp;
1574 // pop float + pointer
1575 pop_( sp, sz_FLOAT + sz_UINT );
1576
1577 // assign
1578 temp.x = (*(t_CKVEC4 **)(sp+sz_FLOAT))->x *= *((t_CKFLOAT *)sp);
1579 temp.y = (*(t_CKVEC4 **)(sp+sz_FLOAT))->y *= *((t_CKFLOAT *)sp);
1580 temp.z = (*(t_CKVEC4 **)(sp+sz_FLOAT))->z *= *((t_CKFLOAT *)sp);
1581 temp.w = (*(t_CKVEC4 **)(sp+sz_FLOAT))->w *= *((t_CKFLOAT *)sp);
1582 // push result
1583 push_( (t_CKVEC4 *&)sp, temp );
1584}
1585
1586
1587
1588
1589//-----------------------------------------------------------------------------
1590// name: execute()
1591// desc: ...
1592//-----------------------------------------------------------------------------
1593void Chuck_Instr_vec4_Divide_float_Assign::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
1594{
1595 t_CKBYTE *& sp = (t_CKBYTE *&)shred->reg->sp;
1596 t_CKVEC4 temp;
1597 // pop float + pointer
1598 pop_( sp, sz_FLOAT + sz_UINT );
1599
1600 // assign
1601 temp.x = (*(t_CKVEC4 **)(sp+sz_FLOAT))->x *= *((t_CKFLOAT *)sp);
1602 temp.y = (*(t_CKVEC4 **)(sp+sz_FLOAT))->y *= *((t_CKFLOAT *)sp);
1603 temp.z = (*(t_CKVEC4 **)(sp+sz_FLOAT))->z *= *((t_CKFLOAT *)sp);
1604 temp.w = (*(t_CKVEC4 **)(sp+sz_FLOAT))->w *= *((t_CKFLOAT *)sp);
1605 // push result
1606 push_( (t_CKVEC4 *&)sp, temp );
1607}
1608
1609
1610
1611#pragma mark === String Arithmetic ===
1612
1613
1614//-----------------------------------------------------------------------------
1615// name: execute()
1616// desc: string + string
1617//-----------------------------------------------------------------------------
1618void Chuck_Instr_Add_string::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
1619{
1620 t_CKUINT *& reg_sp = (t_CKUINT *&)shred->reg->sp;
1621 Chuck_String * lhs = NULL;
1622 Chuck_String * rhs = NULL;
1623 Chuck_String * result = NULL;
1624
1625 // pop word from reg stack
1626 pop_( reg_sp, 2 );
1627 // left
1628 lhs = (Chuck_String *)(*(reg_sp));
1629 // right
1630 rhs = (Chuck_String *)(*(reg_sp+1));
1631
1632 // make sure no null
1633 if( !rhs || !lhs ) goto null_pointer;
1634
1635 // make new string
1636 result = (Chuck_String *)instantiate_and_initialize_object( vm->env()->t_string, shred );
1637
1638 // concat
1639 // result->str = lhs->str + rhs->str;
1640 result->set( lhs->str() + rhs->str() );
1641
1642 // push the reference value to reg stack
1643 push_( reg_sp, (t_CKUINT)(result) );
1644
1645 return;
1646
1647null_pointer:
1648 // we have a problem
1649 CK_FPRINTF_STDERR(
1650 "[chuck](VM): NullPointerException: (string + string) on line[%lu] in shred[id=%lu:%s]\n",
1651 m_linepos, shred->xid, shred->name.c_str() ); // , shred->pc );
1652 goto done;
1653
1654done:
1655 // do something!
1656 shred->is_running = FALSE;
1657 shred->is_done = TRUE;
1658}
1659
1660
1661
1662
1663//-----------------------------------------------------------------------------
1664// name: execute()
1665// desc: add assign string
1666//-----------------------------------------------------------------------------
1667void Chuck_Instr_Add_string_Assign::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
1668{
1669 t_CKUINT *& reg_sp = (t_CKUINT *&)shred->reg->sp;
1670 Chuck_String * lhs = NULL;
1671 Chuck_String ** rhs_ptr = NULL;
1672
1673 // pop word from reg stack
1674 pop_( reg_sp, 2 );
1675 // the previous reference
1676 rhs_ptr = (Chuck_String **)(*(reg_sp+1));
1677 // copy popped value into memory
1678 lhs = (Chuck_String *)(*(reg_sp));
1679
1680 // make sure no null
1681 if( !(*rhs_ptr) ) goto null_pointer;
1682
1683 // concat
1684 // (*rhs_ptr)->str += lhs->str;
1685 (*rhs_ptr)->set( (*rhs_ptr)->str() + lhs->str() );
1686
1687 // push the reference value to reg stack
1688 push_( reg_sp, (t_CKUINT)(*rhs_ptr) );
1689
1690 return;
1691
1692null_pointer:
1693 // we have a problem
1694 CK_FPRINTF_STDERR(
1695 "[chuck](VM): NullPointerException: (string +=> string) on line[%lu] in shred[id=%lu:%s]\n",
1696 m_linepos, shred->xid, shred->name.c_str() );
1697 goto done;
1698
1699done:
1700 // do something!
1701 shred->is_running = FALSE;
1702 shred->is_done = TRUE;
1703}
1704
1705
1706
1707
1708//-----------------------------------------------------------------------------
1709// name: execute()
1710// desc: string + int
1711//-----------------------------------------------------------------------------
1712void Chuck_Instr_Add_string_int::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
1713{
1714 t_CKUINT *& reg_sp = (t_CKUINT *&)shred->reg->sp;
1715 Chuck_String * lhs = NULL;
1716 t_CKINT rhs = 0;
1717 Chuck_String * result = NULL;
1718
1719 // pop word from reg stack
1720 pop_( reg_sp, 2 );
1721 // left
1722 lhs = (Chuck_String *)(*(reg_sp));
1723 // right
1724 rhs = (*(t_CKINT *)(reg_sp+1));
1725
1726 // make sure no null
1727 if( !lhs ) goto null_pointer;
1728
1729 // make new string
1730 result = (Chuck_String *)instantiate_and_initialize_object( vm->env()->t_string, shred );
1731
1732 // concat
1733 // result->str = lhs->str + ::itoa(rhs);
1734 result->set( lhs->str() + ::itoa( rhs ) );
1735
1736 // push the reference value to reg stack
1737 push_( reg_sp, (t_CKUINT)(result) );
1738
1739 return;
1740
1741null_pointer:
1742 // we have a problem
1743 CK_FPRINTF_STDERR(
1744 "[chuck](VM): NullPointerException: (string + int) on line[%lu] in shred[id=%lu:%s]\n",
1745 m_linepos, shred->xid, shred->name.c_str() );
1746 goto done;
1747
1748done:
1749 // do something!
1750 shred->is_running = FALSE;
1751 shred->is_done = TRUE;
1752}
1753
1754
1755
1756
1757//-----------------------------------------------------------------------------
1758// name: execute()
1759// desc: string + float
1760//-----------------------------------------------------------------------------
1761void Chuck_Instr_Add_string_float::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
1762{
1763 t_CKUINT *& reg_sp = (t_CKUINT *&)shred->reg->sp;
1764 Chuck_String * lhs = NULL;
1765 t_CKFLOAT rhs = 0;
1766 Chuck_String * result = NULL;
1767
1768 // pop word from reg stack (1.3.1.0: add size check)
1769 pop_( reg_sp, 1 + (sz_FLOAT / sz_UINT) ); // ISSUE: 64-bit (fixed 1.3.1.0)
1770 // left
1771 lhs = (Chuck_String *)(*(reg_sp));
1772 // right
1773 rhs = (*(t_CKFLOAT *)(reg_sp+1));
1774
1775 // make sure no null
1776 if( !lhs ) goto null_pointer;
1777
1778 // make new string
1779 result = (Chuck_String *)instantiate_and_initialize_object( vm->env()->t_string, shred );
1780
1781 // concat
1782 // result->str = lhs->str + ::ftoa(rhs, 4);
1783 result->set( lhs->str() + ::ftoa( rhs, 4 ) );
1784
1785 // push the reference value to reg stack
1786 push_( reg_sp, (t_CKUINT)(result) );
1787
1788 return;
1789
1790null_pointer:
1791 // we have a problem
1792 CK_FPRINTF_STDERR(
1793 "[chuck](VM): NullPointerException: (string + float) on line[%lu] in shred[id=%lu:%s]\n",
1794 m_linepos, shred->xid, shred->name.c_str() );
1795 goto done;
1796
1797done:
1798 // do something!
1799 shred->is_running = FALSE;
1800 shred->is_done = TRUE;
1801}
1802
1803
1804
1805
1806//-----------------------------------------------------------------------------
1807// name: execute()
1808// desc: int + string
1809//-----------------------------------------------------------------------------
1810void Chuck_Instr_Add_int_string::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
1811{
1812 t_CKUINT *& reg_sp = (t_CKUINT *&)shred->reg->sp;
1813 t_CKINT lhs = 0;
1814 Chuck_String * rhs = NULL;
1815 Chuck_String * result = NULL;
1816
1817 // pop word from reg stack
1818 pop_( reg_sp, 2 );
1819 // left
1820 lhs = (*(t_CKINT *)(reg_sp));
1821 // right
1822 rhs = (Chuck_String *)(*(reg_sp+1));
1823
1824 // make sure no null
1825 if( !rhs ) goto null_pointer;
1826
1827 // make new string
1828 result = (Chuck_String *)instantiate_and_initialize_object( vm->env()->t_string, shred );
1829
1830 // concat
1831 // result->str = ::itoa(lhs) + rhs->str;
1832 result->set( ::itoa(lhs) + rhs->str() );
1833
1834 // push the reference value to reg stack
1835 push_( reg_sp, (t_CKUINT)(result) );
1836
1837 return;
1838
1839null_pointer:
1840 // we have a problem
1841 CK_FPRINTF_STDERR(
1842 "[chuck](VM): NullPointerException: (int + string) on line[%lu] in shred[id=%lu:%s]\n",
1843 m_linepos, shred->xid, shred->name.c_str() );
1844 goto done;
1845
1846done:
1847 // do something!
1848 shred->is_running = FALSE;
1849 shred->is_done = TRUE;
1850}
1851
1852
1853
1854
1855//-----------------------------------------------------------------------------
1856// name: execute()
1857// desc: float + string
1858//-----------------------------------------------------------------------------
1859void Chuck_Instr_Add_float_string::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
1860{
1861 t_CKUINT *& reg_sp = (t_CKUINT *&)shred->reg->sp;
1862 t_CKFLOAT lhs = 0;
1863 Chuck_String * rhs = NULL;
1864 Chuck_String * result = NULL;
1865
1866 // pop word from reg stack (1.3.1.0: added size check)
1867 pop_( reg_sp, 1 + (sz_FLOAT / sz_UINT) ); // ISSUE: 64-bit (fixed 1.3.1.0)
1868 // left (2 word)
1869 lhs = (*(t_CKFLOAT *)(reg_sp));
1870 // right (1.3.1.0: added size)
1871 rhs = (Chuck_String *)(*(reg_sp+(sz_FLOAT/sz_INT))); // ISSUE: 64-bit (fixed 1.3.1.0)
1872
1873 // make sure no null
1874 if( !rhs ) goto null_pointer;
1875
1876 // make new string
1877 result = (Chuck_String *)instantiate_and_initialize_object( vm->env()->t_string, shred );
1878
1879 // concat
1880 // result->str = ::ftoa(lhs, 4) + rhs->str;
1881 result->set( ::ftoa( lhs, 4 ) + rhs->str() );
1882
1883 // push the reference value to reg stack
1884 push_( reg_sp, (t_CKUINT)(result) );
1885
1886 return;
1887
1888null_pointer:
1889 // we have a problem
1890 CK_FPRINTF_STDERR(
1891 "[chuck](VM): NullPointerException: (int + string) on line[%lu] in shred[id=%lu:%s]\n",
1892 m_linepos, shred->xid, shred->name.c_str() );
1893 goto done;
1894
1895done:
1896 // do something!
1897 shred->is_running = FALSE;
1898 shred->is_done = TRUE;
1899}
1900
1901
1902
1903
1904//-----------------------------------------------------------------------------
1905// name: execute()
1906// desc: add assign int string
1907//-----------------------------------------------------------------------------
1908void Chuck_Instr_Add_int_string_Assign::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
1909{
1910 t_CKUINT *& reg_sp = (t_CKUINT *&)shred->reg->sp;
1911 t_CKINT lhs = 0;
1912 Chuck_String ** rhs_ptr = NULL;
1913
1914 // pop word from reg stack
1915 pop_( reg_sp, 2 );
1916 // the previous reference
1917 rhs_ptr = (Chuck_String **)(*(reg_sp+1));
1918 // copy popped value into memory
1919 lhs = (*(t_CKINT *)(reg_sp));
1920
1921 // make sure no null
1922 if( !(*rhs_ptr) ) goto null_pointer;
1923
1924 // concat
1925 // (*rhs_ptr)->str += ::itoa(lhs);
1926 (*rhs_ptr)->set( (*rhs_ptr)->str() + ::itoa(lhs) );
1927
1928 // push the reference value to reg stack
1929 push_( reg_sp, (t_CKUINT)(*rhs_ptr) );
1930
1931 return;
1932
1933null_pointer:
1934 // we have a problem
1935 CK_FPRINTF_STDERR(
1936 "[chuck](VM): NullPointerException: () on line[%lu] in shred[id=%lu:%s]\n",
1937 m_linepos, shred->xid, shred->name.c_str() );
1938 goto done;
1939
1940done:
1941 // do something!
1942 shred->is_running = FALSE;
1943 shred->is_done = TRUE;
1944}
1945
1946
1947
1948
1949//-----------------------------------------------------------------------------
1950// name: execute()
1951// desc: add assign float string
1952//-----------------------------------------------------------------------------
1953void Chuck_Instr_Add_float_string_Assign::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
1954{
1955 t_CKUINT *& reg_sp = (t_CKUINT *&)shred->reg->sp;
1956 t_CKFLOAT lhs = 0;
1957 Chuck_String ** rhs_ptr = NULL;
1958
1959 // pop word from reg stack (1.3.1.0: added size check)
1960 pop_( reg_sp, 1 + (sz_FLOAT / sz_UINT) ); // ISSUE: 64-bit (fixed 1.3.1.0)
1961 // the previous reference (1.3.1.0: added size check)
1962 rhs_ptr = (Chuck_String **)(*(reg_sp+(sz_FLOAT/sz_UINT))); // ISSUE: 64-bit (fixed 1.3.1.0)
1963 // copy popped value into memory
1964 lhs = (*(t_CKFLOAT *)(reg_sp));
1965
1966 // make sure no null
1967 if( !(*rhs_ptr) ) goto null_pointer;
1968
1969 // concat
1970 // (*rhs_ptr)->str += ::ftoa(lhs, 4);
1971 (*rhs_ptr)->set( (*rhs_ptr)->str() + ::ftoa(lhs, 4) );
1972
1973 // push the reference value to reg stack
1974 push_( reg_sp, (t_CKUINT)(*rhs_ptr) );
1975
1976 return;
1977
1978null_pointer:
1979 // we have a problem
1980 CK_FPRINTF_STDERR(
1981 "[chuck](VM): NullPointerException: (string + string) on line[%lu] in shred[id=%lu:%s]\n",
1982 m_linepos, shred->xid, shred->name.c_str() );
1983 goto done;
1984
1985done:
1986 // do something!
1987 shred->is_running = FALSE;
1988 shred->is_done = TRUE;
1989}
1990
1991
1992
1993#pragma mark === Stack Operations ===
1994
1995
1996//-----------------------------------------------------------------------------
1997// name: execute()
1998// desc: ...
1999//-----------------------------------------------------------------------------
2000void Chuck_Instr_Reg_Push_Imm::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
2001{
2002 t_CKUINT *& reg_sp = (t_CKUINT *&)shred->reg->sp;
2003
2004 // push val into reg stack
2005 push_( reg_sp, m_val );
2006}
2007
2008
2009
2010
2011//-----------------------------------------------------------------------------
2012// name: execute()
2013// desc: ...
2014//-----------------------------------------------------------------------------
2015void Chuck_Instr_Reg_Push_Imm2::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
2016{
2017 t_CKFLOAT *& reg_sp = (t_CKFLOAT *&)shred->reg->sp;
2018
2019 // push val into reg stack
2020 push_( reg_sp, m_val );
2021}
2022
2023
2024
2025
2026//-----------------------------------------------------------------------------
2027// name: execute()
2028// desc: ...
2029//-----------------------------------------------------------------------------
2030void Chuck_Instr_Reg_Push_Imm4::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
2031{
2032 t_CKFLOAT *& reg_sp = (t_CKFLOAT *&)shred->reg->sp;
2033
2034 // push val into reg stack
2035 push_( reg_sp, m_val );
2036 push_( reg_sp, m_val2 );
2037}
2038
2039
2040
2041
2042//-----------------------------------------------------------------------------
2043// name: execute()
2044// desc: ...
2045//-----------------------------------------------------------------------------
2046void Chuck_Instr_Reg_Dup_Last::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
2047{
2048 t_CKUINT *& reg_sp = (t_CKUINT *&)shred->reg->sp;
2049
2050 // dup val into reg stack
2051 push_( reg_sp, *(reg_sp-1) );
2052}
2053
2054
2055
2056
2057//-----------------------------------------------------------------------------
2058// name: execute()
2059// desc: ...
2060//-----------------------------------------------------------------------------
2061void Chuck_Instr_Reg_Dup_Last2::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
2062{
2063 t_CKFLOAT *& reg_sp = (t_CKFLOAT *&)shred->reg->sp;
2064
2065 // dup val into reg stack
2066 push_( reg_sp, *(reg_sp-1) );
2067}
2068
2069
2070
2071
2072//-----------------------------------------------------------------------------
2073// name: execute()
2074// desc: ...
2075//-----------------------------------------------------------------------------
2076void Chuck_Instr_Reg_Dup_Last_As_Pointer::execute(
2077 Chuck_VM * vm, Chuck_VM_Shred * shred )
2078{
2079 t_CKUINT *& reg_sp = (t_CKUINT *&)shred->reg->sp;
2080 t_CKBYTE * where = (t_CKBYTE *)shred->reg->sp;
2081
2082 // push pointer into reg stack
2083 push_( reg_sp, (t_CKUINT)(where-(m_val*sz_WORD)) );
2084}
2085
2086
2087
2088
2089//-----------------------------------------------------------------------------
2090// name: execute()
2091// desc: ...
2092//-----------------------------------------------------------------------------
2093void Chuck_Instr_Reg_Push_Now::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
2094{
2095 t_CKTIME *& reg_sp = (t_CKTIME *&)shred->reg->sp;
2096
2097 // push val into reg stack
2098 push_( reg_sp, shred->now );
2099}
2100
2101
2102
2103
2104//-----------------------------------------------------------------------------
2105// name: execute()
2106// desc: ...
2107//-----------------------------------------------------------------------------
2108void Chuck_Instr_Reg_Push_Me::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
2109{
2110 t_CKUINT *& reg_sp = (t_CKUINT *&)shred->reg->sp;
2111
2112 // push val into reg stack
2113 push_( reg_sp, (t_CKUINT)shred );
2114}
2115
2116
2117
2118
2119//-----------------------------------------------------------------------------
2120// name: execute()
2121// desc: ...
2122//-----------------------------------------------------------------------------
2123void Chuck_Instr_Reg_Push_This::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
2124{
2125 t_CKUINT *& reg_sp = (t_CKUINT *&)shred->reg->sp;
2126 t_CKUINT *& mem_sp = (t_CKUINT *&)shred->mem->sp;
2127
2128 // push val into reg stack
2129 push_( reg_sp, *(mem_sp) );
2130}
2131
2132
2133
2134
2135//-----------------------------------------------------------------------------
2136// name: execute()
2137// desc: ...
2138//-----------------------------------------------------------------------------
2139void Chuck_Instr_Reg_Push_Start::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
2140{
2141 t_CKTIME *& reg_sp = (t_CKTIME *&)shred->reg->sp;
2142
2143 // push val into reg stack
2144 push_( reg_sp, shred->start );
2145}
2146
2147
2148
2149
2150//-----------------------------------------------------------------------------
2151// name: execute()
2152// desc: ...
2153//-----------------------------------------------------------------------------
2154void Chuck_Instr_Reg_Push_Maybe::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
2155{
2156 t_CKINT *& reg_sp = (t_CKINT *&)shred->reg->sp;
2157
2158 // push val into reg stack
2159 float num = (float)rand() / (float)RAND_MAX;
2160 push_( reg_sp, num > .5 );
2161}
2162
2163
2164
2165
2166//-----------------------------------------------------------------------------
2167// name: execute()
2168// desc: push the value pointed to by m_val onto register stack
2169//-----------------------------------------------------------------------------
2170void Chuck_Instr_Reg_Push_Deref::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
2171{
2172 t_CKUINT *& reg_sp = (t_CKUINT *&)shred->reg->sp;
2173
2174 // (added 1.3.1.0: made this integer only)
2175 // ISSUE: 64-bit (fixed 1.3.1.0)
2176 push_( reg_sp, *((t_CKUINT *)m_val) );
2177}
2178
2179
2180
2181
2182//-----------------------------------------------------------------------------
2183// name: execute()
2184// desc: push the value pointed to by m_val onto register stack
2185//-----------------------------------------------------------------------------
2186void Chuck_Instr_Reg_Push_Deref2::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
2187{
2188 t_CKFLOAT *& reg_sp = (t_CKFLOAT *&)shred->reg->sp;
2189
2190 // (added 1.3.1.0)
2191 push_( reg_sp, *((t_CKFLOAT *)m_val) );
2192}
2193
2194
2195
2196
2197//-----------------------------------------------------------------------------
2198// name: execute()
2199// desc: push value from memory stack to register stack
2200//-----------------------------------------------------------------------------
2201void Chuck_Instr_Reg_Push_Mem::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
2202{
2203 t_CKBYTE *& mem_sp = (t_CKBYTE *&)(base?shred->base_ref->stack:shred->mem->sp);
2204 t_CKUINT *& reg_sp = (t_CKUINT *&)shred->reg->sp;
2205
2206 // push mem stack content into reg stack
2207 push_( reg_sp, *((t_CKUINT *)(mem_sp + m_val)) );
2208}
2209
2210
2211
2212
2213//-----------------------------------------------------------------------------
2214// name: execute()
2215// desc: ...
2216//-----------------------------------------------------------------------------
2217void Chuck_Instr_Reg_Push_Mem2::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
2218{
2219 t_CKBYTE *& mem_sp = (t_CKBYTE *&)(base?shred->base_ref->stack:shred->mem->sp);
2220 t_CKFLOAT *& reg_sp = (t_CKFLOAT *&)shred->reg->sp;
2221
2222 // push mem stack content into reg stack
2223 push_( reg_sp, *((t_CKFLOAT *)(mem_sp + m_val)) );
2224}
2225
2226
2227
2228
2229//-----------------------------------------------------------------------------
2230// name: execute()
2231// desc: ...
2232//-----------------------------------------------------------------------------
2233void Chuck_Instr_Reg_Push_Mem4::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
2234{
2235 t_CKBYTE *& mem_sp = (t_CKBYTE *&)(base?shred->base_ref->stack:shred->mem->sp);
2236 t_CKCOMPLEX *& reg_sp = (t_CKCOMPLEX *&)shred->reg->sp;
2237
2238 // push mem stack content into reg stack
2239 push_( reg_sp, *((t_CKCOMPLEX *)(mem_sp + m_val)) );
2240}
2241
2242
2243
2244
2245//-----------------------------------------------------------------------------
2246// name: execute()
2247// desc: ...
2248//-----------------------------------------------------------------------------
2249void Chuck_Instr_Reg_Push_Mem_Vec3::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
2250{
2251 t_CKBYTE *& mem_sp = (t_CKBYTE *&)(base?shred->base_ref->stack:shred->mem->sp);
2252 t_CKVEC3 *& reg_sp = (t_CKVEC3 *&)shred->reg->sp;
2253
2254 // push mem stack content into reg stack
2255 push_( reg_sp, *((t_CKVEC3 *)(mem_sp + m_val)) );
2256}
2257
2258
2259
2260
2261//-----------------------------------------------------------------------------
2262// name: execute()
2263// desc: ...
2264//-----------------------------------------------------------------------------
2265void Chuck_Instr_Reg_Push_Mem_Vec4::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
2266{
2267 t_CKBYTE *& mem_sp = (t_CKBYTE *&)(base?shred->base_ref->stack:shred->mem->sp);
2268 t_CKVEC4 *& reg_sp = (t_CKVEC4 *&)shred->reg->sp;
2269
2270 // push mem stack content into reg stack
2271 push_( reg_sp, *((t_CKVEC4 *)(mem_sp + m_val)) );
2272}
2273
2274
2275
2276
2277//-----------------------------------------------------------------------------
2278// name: execute()
2279// desc: push value from external maps to register stack
2280//-----------------------------------------------------------------------------
2281void Chuck_Instr_Reg_Push_External::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
2282{
2283
2284 // get external map content
2285 switch( m_type ) {
2286 case te_externalInt:
2287 {
2288 // int pointer to registers
2289 t_CKUINT *& reg_sp = (t_CKUINT *&)shred->reg->sp;
2290 t_CKUINT val = (t_CKUINT) vm->get_external_int_value( m_name );
2291
2292 // push external map content into int-reg stack
2293 push_( reg_sp, val );
2294 }
2295 break;
2296 case te_externalFloat:
2297 {
2298 // float pointer to registers
2299 t_CKFLOAT *& reg_sp = (t_CKFLOAT *&)shred->reg->sp;
2300 t_CKFLOAT val = (t_CKFLOAT) vm->get_external_float_value( m_name );
2301
2302 // push external map content into float-reg stack
2303 push_( reg_sp, val );
2304 }
2305 break;
2306 case te_externalEvent:
2307 {
2308 t_CKUINT *& reg_sp = (t_CKUINT *&)shred->reg->sp;
2309 t_CKUINT val = (t_CKUINT) vm->get_external_event( m_name );
2310
2311 // push external map content into event-reg stack
2312 push_( reg_sp, val );
2313 }
2314 break;
2315 }
2316}
2317
2318
2319
2320
2321//-----------------------------------------------------------------------------
2322// name: execute()
2323// desc: ...
2324//-----------------------------------------------------------------------------
2325void Chuck_Instr_Reg_Push_Mem_Addr::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
2326{
2327 t_CKBYTE *& mem_sp = (t_CKBYTE *&)(base?shred->base_ref->stack:shred->mem->sp);
2328 t_CKUINT *& reg_sp = (t_CKUINT *&)shred->reg->sp;
2329
2330 // push mem stack addr into reg stack
2331 push_( reg_sp, (t_CKUINT)(mem_sp + m_val) );
2332}
2333
2334
2335
2336
2337//-----------------------------------------------------------------------------
2338// name: execute()
2339// desc: ...
2340//-----------------------------------------------------------------------------
2341void Chuck_Instr_Reg_Push_External_Addr::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
2342{
2343 t_CKUINT *& reg_sp = (t_CKUINT *&)shred->reg->sp;
2344
2345 // find addr
2346 t_CKUINT addr;
2347 switch( m_type ) {
2348 case te_externalInt:
2349 addr = (t_CKUINT) vm->get_ptr_to_external_int( m_name );
2350 break;
2351 case te_externalFloat:
2352 addr = (t_CKUINT) vm->get_ptr_to_external_float( m_name );
2353 break;
2354 case te_externalEvent:
2355 addr = (t_CKUINT) vm->get_ptr_to_external_event( m_name );
2356 break;
2357
2358 }
2359
2360 // push mem stack addr into reg stack
2361 push_( reg_sp, addr );
2362}
2363
2364
2365
2366
2367//-----------------------------------------------------------------------------
2368// name: execute()
2369// desc: ...
2370//-----------------------------------------------------------------------------
2371void Chuck_Instr_Reg_Pop_Mem::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
2372{
2373 t_CKBYTE *& mem_sp = (t_CKBYTE *&)shred->mem->sp;
2374 t_CKUINT *& reg_sp = (t_CKUINT *&)shred->reg->sp;
2375
2376 // pop word from reg stack
2377 pop_( reg_sp, 2 );
2378 // copy popped value into mem stack
2379 *((t_CKUINT *)(mem_sp + *(reg_sp+1) )) = *reg_sp;
2380}
2381
2382
2383
2384
2385//-----------------------------------------------------------------------------
2386// name: execute()
2387// desc: ...
2388//-----------------------------------------------------------------------------
2389void Chuck_Instr_Reg_Pop_Word::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
2390{
2391 t_CKUINT *& reg_sp = (t_CKUINT *&)shred->reg->sp;
2392
2393 // pop word from reg stack
2394 pop_( reg_sp, 1 );
2395}
2396
2397
2398
2399
2400//-----------------------------------------------------------------------------
2401// name: execute()
2402// desc: ...
2403//-----------------------------------------------------------------------------
2404void Chuck_Instr_Reg_Pop_Word2::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
2405{
2406 t_CKFLOAT *& reg_sp = (t_CKFLOAT *&)shred->reg->sp;
2407
2408 // pop word from reg stack
2409 pop_( reg_sp, 1 );
2410}
2411
2412
2413
2414
2415//-----------------------------------------------------------------------------
2416// name: execute()
2417// desc: ...
2418//-----------------------------------------------------------------------------
2419void Chuck_Instr_Reg_Pop_Word3::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
2420{
2421 t_CKCOMPLEX *& reg_sp = (t_CKCOMPLEX *&)shred->reg->sp;
2422
2423 // pop word from reg stack
2424 pop_( reg_sp, 1 );
2425}
2426
2427
2428
2429
2430//-----------------------------------------------------------------------------
2431// name: execute()
2432// desc: ...
2433//-----------------------------------------------------------------------------
2434void Chuck_Instr_Reg_Pop_Word4::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
2435{
2436 t_CKBYTE *& reg_sp = (t_CKBYTE *&)shred->reg->sp;
2437
2438 // pop word from reg stack (changed 1.3.1.0 to use sz_WORD)
2439 pop_( reg_sp, m_val * sz_WORD );
2440}
2441
2442
2443
2444
2445#pragma mark === Memory Operations ===
2446
2447
2448
2449//-----------------------------------------------------------------------------
2450// name: execute()
2451// desc: ...
2452//-----------------------------------------------------------------------------
2453void Chuck_Instr_Mem_Set_Imm::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
2454{
2455 t_CKUINT * mem_sp = (t_CKUINT *)(shred->mem->sp + m_offset);
2456
2457 // set
2458 *(mem_sp) = m_val;
2459}
2460
2461
2462
2463
2464//-----------------------------------------------------------------------------
2465// name: execute()
2466// desc: ...
2467//-----------------------------------------------------------------------------
2468void Chuck_Instr_Mem_Set_Imm2::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
2469{
2470 t_CKFLOAT * mem_sp = (t_CKFLOAT *)(shred->mem->sp + m_offset);
2471
2472 // set
2473 *(mem_sp) = m_val;
2474}
2475
2476
2477
2478
2479//-----------------------------------------------------------------------------
2480// name: execute()
2481// desc: ...
2482//-----------------------------------------------------------------------------
2483void Chuck_Instr_Mem_Push_Imm::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
2484{
2485 t_CKUINT *& mem_sp = (t_CKUINT *&)shred->mem->sp;
2486
2487 // pop word from reg stack
2488 push_( mem_sp, m_val );
2489}
2490
2491
2492
2493
2494//-----------------------------------------------------------------------------
2495// name: execute()
2496// desc: ...
2497//-----------------------------------------------------------------------------
2498void Chuck_Instr_Mem_Push_Imm2::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
2499{
2500 t_CKFLOAT *& mem_sp = (t_CKFLOAT *&)shred->mem->sp;
2501
2502 // pop word from reg stack
2503 push_( mem_sp, m_val );
2504}
2505
2506
2507
2508
2509//-----------------------------------------------------------------------------
2510// name: execute()
2511// desc: ...
2512//-----------------------------------------------------------------------------
2513void Chuck_Instr_Mem_Pop_Word::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
2514{
2515 t_CKUINT *& mem_sp = (t_CKUINT *&)shred->mem->sp;
2516
2517 // pop word from reg stack
2518 pop_( mem_sp, 1 );
2519}
2520
2521
2522
2523
2524//-----------------------------------------------------------------------------
2525// name: execute()
2526// desc: ...
2527//-----------------------------------------------------------------------------
2528void Chuck_Instr_Mem_Pop_Word2::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
2529{
2530 t_CKFLOAT *& mem_sp = (t_CKFLOAT *&)shred->mem->sp;
2531
2532 // pop word from reg stack
2533 pop_( mem_sp, 1 );
2534}
2535
2536
2537
2538
2539//-----------------------------------------------------------------------------
2540// name: execute()
2541// desc: ...
2542//-----------------------------------------------------------------------------
2543void Chuck_Instr_Mem_Pop_Word3::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
2544{
2545 t_CKUINT *& mem_sp = (t_CKUINT *&)shred->mem->sp;
2546
2547 // pop word from reg stack
2548 pop_( mem_sp, m_val );
2549}
2550
2551
2552
2553#pragma mark === Branching ===
2554
2555
2556//-----------------------------------------------------------------------------
2557// name: execute()
2558// desc: ...
2559//-----------------------------------------------------------------------------
2560void Chuck_Instr_Branch_Lt_int::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
2561{
2562 t_CKINT *& sp = (t_CKINT *&)shred->reg->sp;
2563 pop_( sp, 2 );
2564 if( val_(sp) < val_(sp+1) )
2565 shred->next_pc = m_jmp;
2566}
2567
2568
2569
2570
2571//-----------------------------------------------------------------------------
2572// name: execute()
2573// desc: ...
2574//-----------------------------------------------------------------------------
2575void Chuck_Instr_Branch_Gt_int::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
2576{
2577 t_CKINT *& sp = (t_CKINT *&)shred->reg->sp;
2578 pop_( sp, 2 );
2579 if( val_(sp) > val_(sp+1) )
2580 shred->next_pc = m_jmp;
2581}
2582
2583
2584
2585
2586//-----------------------------------------------------------------------------
2587// name: execute()
2588// desc: ...
2589//-----------------------------------------------------------------------------
2590void Chuck_Instr_Branch_Le_int::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
2591{
2592 t_CKINT *& sp = (t_CKINT *&)shred->reg->sp;
2593 pop_( sp, 2 );
2594 if( val_(sp) <= val_(sp+1) )
2595 shred->next_pc = m_jmp;
2596}
2597
2598
2599
2600
2601//-----------------------------------------------------------------------------
2602// name: execute()
2603// desc: ...
2604//-----------------------------------------------------------------------------
2605void Chuck_Instr_Branch_Ge_int::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
2606{
2607 t_CKINT *& sp = (t_CKINT *&)shred->reg->sp;
2608 pop_( sp, 2 );
2609 if( val_(sp) >= val_(sp+1) )
2610 shred->next_pc = m_jmp;
2611}
2612
2613
2614
2615
2616//-----------------------------------------------------------------------------
2617// name: execute()
2618// desc: ...
2619//-----------------------------------------------------------------------------
2620void Chuck_Instr_Branch_Eq_int::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
2621{
2622 t_CKINT *& sp = (t_CKINT *&)shred->reg->sp;
2623 pop_( sp, 2 );
2624 if( val_(sp) == val_(sp+1) )
2625 shred->next_pc = m_jmp;
2626}
2627
2628
2629
2630
2631//-----------------------------------------------------------------------------
2632// name: execute()
2633// desc: ...
2634//-----------------------------------------------------------------------------
2635void Chuck_Instr_Branch_Neq_int::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
2636{
2637 t_CKINT *& sp = (t_CKINT *&)shred->reg->sp;
2638 pop_( sp, 2 );
2639 if( val_(sp) != val_(sp+1) )
2640 shred->next_pc = m_jmp;
2641}
2642
2643
2644
2645
2646//-----------------------------------------------------------------------------
2647// name: execute()
2648// desc: ...
2649//-----------------------------------------------------------------------------
2650void Chuck_Instr_Not_int::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
2651{
2652 t_CKINT *& sp = (t_CKINT *&)shred->reg->sp;
2653 (*(sp-1)) = !(*(sp-1));
2654}
2655
2656
2657
2658
2659//-----------------------------------------------------------------------------
2660// name: execute()
2661// desc: ...
2662//-----------------------------------------------------------------------------
2663void Chuck_Instr_Negate_int::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
2664{
2665 t_CKINT *& sp = (t_CKINT *&)shred->reg->sp;
2666 (*(sp-1)) = -(*(sp-1));
2667}
2668
2669
2670
2671
2672//-----------------------------------------------------------------------------
2673// name: execute()
2674// desc: ...
2675//-----------------------------------------------------------------------------
2676void Chuck_Instr_Negate_double::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
2677{
2678 t_CKFLOAT *& sp = (t_CKFLOAT *&)shred->reg->sp;
2679 (*(sp-1)) = -(*(sp-1));
2680}
2681
2682
2683
2684
2685//-----------------------------------------------------------------------------
2686// name: execute()
2687// desc: ...
2688//-----------------------------------------------------------------------------
2689void Chuck_Instr_Branch_Lt_double::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
2690{
2691 t_CKFLOAT *& sp = (t_CKFLOAT *&)shred->reg->sp;
2692 pop_( sp, 2 );
2693 if( val_(sp) < val_(sp+1) )
2694 shred->next_pc = m_jmp;
2695}
2696
2697
2698
2699
2700//-----------------------------------------------------------------------------
2701// name: execute()
2702// desc: ...
2703//-----------------------------------------------------------------------------
2704void Chuck_Instr_Branch_Gt_double::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
2705{
2706 t_CKFLOAT *& sp = (t_CKFLOAT *&)shred->reg->sp;
2707 pop_( sp, 2 );
2708 if( val_(sp) > val_(sp+1) )
2709 shred->next_pc = m_jmp;
2710}
2711
2712
2713
2714
2715//-----------------------------------------------------------------------------
2716// name: execute()
2717// desc: ...
2718//-----------------------------------------------------------------------------
2719void Chuck_Instr_Branch_Le_double::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
2720{
2721 t_CKFLOAT *& sp = (t_CKFLOAT *&)shred->reg->sp;
2722 pop_( sp, 2 );
2723 if( val_(sp) <= val_(sp+1) )
2724 shred->next_pc = m_jmp;
2725}
2726
2727
2728
2729
2730//-----------------------------------------------------------------------------
2731// name: execute()
2732// desc: ...
2733//-----------------------------------------------------------------------------
2734void Chuck_Instr_Branch_Ge_double::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
2735{
2736 t_CKFLOAT *& sp = (t_CKFLOAT *&)shred->reg->sp;
2737 pop_( sp, 2 );
2738 if( val_(sp) >= val_(sp+1) )
2739 shred->next_pc = m_jmp;
2740}
2741
2742
2743
2744
2745//-----------------------------------------------------------------------------
2746// name: execute()
2747// desc: ...
2748//-----------------------------------------------------------------------------
2749void Chuck_Instr_Branch_Eq_double::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
2750{
2751 t_CKFLOAT *& sp = (t_CKFLOAT *&)shred->reg->sp;
2752 pop_( sp, 2 );
2753 if( val_(sp) == val_(sp+1) )
2754 shred->next_pc = m_jmp;
2755}
2756
2757
2758
2759
2760//-----------------------------------------------------------------------------
2761// name: execute()
2762// desc: ...
2763//-----------------------------------------------------------------------------
2764void Chuck_Instr_Branch_Neq_double::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
2765{
2766 t_CKFLOAT *& sp = (t_CKFLOAT *&)shred->reg->sp;
2767 pop_( sp, 2 );
2768 if( val_(sp) != val_(sp+1) )
2769 shred->next_pc = m_jmp;
2770}
2771
2772
2773
2774
2775//-----------------------------------------------------------------------------
2776// name: execute()
2777// desc: ...
2778//-----------------------------------------------------------------------------
2779void Chuck_Instr_Branch_Eq_int_IO_good::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
2780{
2781 t_CKINT *& sp = (t_CKINT *&)shred->reg->sp;
2782 Chuck_IO **& ppIO = (Chuck_IO **&)shred->reg->sp;
2783 t_CKINT result = 0;
2784 pop_( sp, 2 );
2785
2786 if( (*ppIO) != NULL )
2787 {
2788 // TODO: verify this logic
2789 result = (*ppIO)->good() && !(*ppIO)->eof();
2790 }
2791
2792 if( result == val_(sp+1) || !(*ppIO) )
2793 shred->next_pc = m_jmp;
2794}
2795
2796
2797
2798
2799//-----------------------------------------------------------------------------
2800// name: execute()
2801// desc: ...
2802//-----------------------------------------------------------------------------
2803void Chuck_Instr_Branch_Neq_int_IO_good::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
2804{
2805 t_CKINT *& sp = (t_CKINT *&)shred->reg->sp;
2806 Chuck_IO **& ppIO = (Chuck_IO **&)shred->reg->sp;
2807 t_CKINT result = 0;
2808 pop_( sp, 2 );
2809
2810 if( (*ppIO) != NULL )
2811 {
2812 // fixed 1.3.0.0 -- removed the t_CKINT
2813 // TODO: verify this logic?
2814 result = (*ppIO)->good() && !(*ppIO)->eof();
2815 }
2816
2817 if( result != val_(sp+1) || !(ppIO) )
2818 shred->next_pc = m_jmp;
2819}
2820
2821
2822
2823#pragma mark === Bitwise Arithmetic ===
2824
2825
2826//-----------------------------------------------------------------------------
2827// name: execute()
2828// desc: ...
2829//-----------------------------------------------------------------------------
2830void Chuck_Instr_Binary_And::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
2831{
2832 t_CKUINT *& sp = (t_CKUINT *&)shred->reg->sp;
2833 pop_( sp, 2 );
2834 push_( sp, val_(sp) & val_(sp+1) );
2835}
2836
2837
2838
2839
2840//-----------------------------------------------------------------------------
2841// name: execute()
2842// desc: ...
2843//-----------------------------------------------------------------------------
2844void Chuck_Instr_Binary_Or::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
2845{
2846 t_CKUINT *& sp = (t_CKUINT *&)shred->reg->sp;
2847 pop_( sp, 2 );
2848 push_( sp, val_(sp) | val_(sp+1) );
2849}
2850
2851
2852
2853
2854//-----------------------------------------------------------------------------
2855// name: execute()
2856// desc: ...
2857//-----------------------------------------------------------------------------
2858void Chuck_Instr_Binary_Xor::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
2859{
2860 t_CKUINT *& sp = (t_CKUINT *&)shred->reg->sp;
2861 pop_( sp, 2 );
2862 push_( sp, val_(sp) ^ val_(sp+1) );
2863}
2864
2865
2866
2867
2868//-----------------------------------------------------------------------------
2869// name: execute()
2870// desc: ...
2871//-----------------------------------------------------------------------------
2872void Chuck_Instr_Binary_Shift_Right::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
2873{
2874 t_CKUINT *& sp = (t_CKUINT *&)shred->reg->sp;
2875 pop_( sp, 2 );
2876 push_( sp, val_(sp) >> val_(sp+1) );
2877}
2878
2879
2880
2881
2882//-----------------------------------------------------------------------------
2883// name: execute()
2884// desc: ...
2885//-----------------------------------------------------------------------------
2886void Chuck_Instr_Binary_Shift_Right_Reverse::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
2887{
2888 t_CKUINT *& sp = (t_CKUINT *&)shred->reg->sp;
2889 pop_( sp, 2 );
2890 push_( sp, val_(sp+1) >> val_(sp) );
2891}
2892
2893
2894
2895
2896//-----------------------------------------------------------------------------
2897// name: execute()
2898// desc: ...
2899//-----------------------------------------------------------------------------
2900void Chuck_Instr_Binary_Shift_Left::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
2901{
2902 t_CKUINT *& sp = (t_CKUINT *&)shred->reg->sp;
2903 pop_( sp, 2 );
2904 push_( sp, val_(sp) << val_(sp+1) );
2905}
2906
2907
2908
2909
2910//-----------------------------------------------------------------------------
2911// name: execute()
2912// desc: ...
2913//-----------------------------------------------------------------------------
2914void Chuck_Instr_Binary_Shift_Left_Reverse::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
2915{
2916 t_CKUINT *& sp = (t_CKUINT *&)shred->reg->sp;
2917 pop_( sp, 2 );
2918 push_( sp, val_(sp+1) << val_(sp) );
2919}
2920
2921
2922
2923
2924//-----------------------------------------------------------------------------
2925// name: execute()
2926// desc: ...
2927//-----------------------------------------------------------------------------
2928void Chuck_Instr_Binary_And_Assign::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
2929{
2930 t_CKINT temp, *& sp = (t_CKINT *&)shred->reg->sp;
2931 pop_( sp, 2 );
2932 temp = **(t_CKINT **)(sp+1) &= val_(sp);
2933 push_( sp, temp );
2934}
2935
2936
2937
2938
2939//-----------------------------------------------------------------------------
2940// name: execute()
2941// desc: ...
2942//-----------------------------------------------------------------------------
2943void Chuck_Instr_Binary_Or_Assign::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
2944{
2945 t_CKINT temp, *& sp = (t_CKINT *&)shred->reg->sp;
2946 pop_( sp, 2 );
2947 temp = **(t_CKINT **)(sp+1) |= val_(sp);
2948 push_( sp, temp );
2949}
2950
2951
2952
2953
2954//-----------------------------------------------------------------------------
2955// name: execute()
2956// desc: ...
2957//-----------------------------------------------------------------------------
2958void Chuck_Instr_Binary_Xor_Assign::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
2959{
2960 t_CKINT temp, *& sp = (t_CKINT *&)shred->reg->sp;
2961 pop_( sp, 2 );
2962 temp = **(t_CKINT **)(sp+1) ^= val_(sp);
2963 push_( sp, temp );
2964}
2965
2966
2967
2968
2969//-----------------------------------------------------------------------------
2970// name: execute()
2971// desc: ...
2972//-----------------------------------------------------------------------------
2973void Chuck_Instr_Binary_Shift_Right_Assign::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
2974{
2975 t_CKINT temp, *& sp = (t_CKINT *&)shred->reg->sp;
2976 pop_( sp, 2 );
2977 temp = **(t_CKINT **)(sp+1) >>= val_(sp);
2978 push_( sp, temp );
2979}
2980
2981
2982
2983
2984//-----------------------------------------------------------------------------
2985// name: execute()
2986// desc: ...
2987//-----------------------------------------------------------------------------
2988void Chuck_Instr_Binary_Shift_Left_Assign::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
2989{
2990 t_CKINT temp, *& sp = (t_CKINT *&)shred->reg->sp;
2991 pop_( sp, 2 );
2992 temp = **(t_CKINT **)(sp+1) <<= val_(sp);
2993 push_( sp, temp );
2994}
2995
2996
2997
2998#pragma mark === Comparison ===
2999
3000
3001//-----------------------------------------------------------------------------
3002// name: execute()
3003// desc: ...
3004//-----------------------------------------------------------------------------
3005void Chuck_Instr_Lt_int::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
3006{
3007 t_CKINT *& sp = (t_CKINT *&)shred->reg->sp;
3008 pop_( sp, 2 );
3009 push_( sp, val_(sp) < val_(sp+1) );
3010}
3011
3012
3013
3014
3015//-----------------------------------------------------------------------------
3016// name: execute()
3017// desc: ...
3018//-----------------------------------------------------------------------------
3019void Chuck_Instr_Gt_int::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
3020{
3021 t_CKINT *& sp = (t_CKINT *&)shred->reg->sp;
3022 pop_( sp, 2 );
3023 push_( sp, val_(sp) > val_(sp+1) );
3024}
3025
3026
3027
3028
3029//-----------------------------------------------------------------------------
3030// name: execute()
3031// desc: ...
3032//-----------------------------------------------------------------------------
3033void Chuck_Instr_Le_int::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
3034{
3035 t_CKINT *& sp = (t_CKINT *&)shred->reg->sp;
3036 pop_( sp, 2 );
3037 push_( sp, val_(sp) <= val_(sp+1) );
3038}
3039
3040
3041
3042
3043//-----------------------------------------------------------------------------
3044// name: execute()
3045// desc: ...
3046//-----------------------------------------------------------------------------
3047void Chuck_Instr_Ge_int::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
3048{
3049 t_CKINT *& sp = (t_CKINT *&)shred->reg->sp;
3050 pop_( sp, 2 );
3051 push_( sp, val_(sp) >= val_(sp+1) );
3052}
3053
3054
3055
3056
3057//-----------------------------------------------------------------------------
3058// name: execute()
3059// desc: ...
3060//-----------------------------------------------------------------------------
3061void Chuck_Instr_Eq_int::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
3062{
3063 t_CKINT *& sp = (t_CKINT *&)shred->reg->sp;
3064 pop_( sp, 2 );
3065 push_( sp, val_(sp) == val_(sp+1) );
3066}
3067
3068
3069
3070
3071//-----------------------------------------------------------------------------
3072// name: execute()
3073// desc: ...
3074//-----------------------------------------------------------------------------
3075void Chuck_Instr_Neq_int::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
3076{
3077 t_CKINT *& sp = (t_CKINT *&)shred->reg->sp;
3078 pop_( sp, 2 );
3079 push_( sp, val_(sp) != val_(sp+1) );
3080}
3081
3082
3083
3084
3085//-----------------------------------------------------------------------------
3086// name: execute()
3087// desc: ...
3088//-----------------------------------------------------------------------------
3089void Chuck_Instr_Lt_double::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
3090{
3091 t_CKFLOAT *& sp = (t_CKFLOAT *&)shred->reg->sp;
3092 t_CKUINT *& sp_uint = (t_CKUINT *&)sp;
3093 pop_( sp, 2 );
3094 push_( sp_uint, val_(sp) < val_(sp+1) );
3095}
3096
3097
3098
3099
3100//-----------------------------------------------------------------------------
3101// name: execute()
3102// desc: ...
3103//-----------------------------------------------------------------------------
3104void Chuck_Instr_Gt_double::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
3105{
3106 t_CKFLOAT *& sp = (t_CKFLOAT *&)shred->reg->sp;
3107 t_CKUINT *& sp_uint = (t_CKUINT *&)sp;
3108 pop_( sp, 2 );
3109 push_( sp_uint, val_(sp) > val_(sp+1) );
3110}
3111
3112
3113
3114
3115//-----------------------------------------------------------------------------
3116// name: execute()
3117// desc: ...
3118//-----------------------------------------------------------------------------
3119void Chuck_Instr_Le_double::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
3120{
3121 t_CKFLOAT *& sp = (t_CKFLOAT *&)shred->reg->sp;
3122 t_CKUINT *& sp_uint = (t_CKUINT *&)sp;
3123 pop_( sp, 2 );
3124 push_( sp_uint, val_(sp) <= val_(sp+1) );
3125}
3126
3127
3128
3129
3130//-----------------------------------------------------------------------------
3131// name: execute()
3132// desc: ...
3133//-----------------------------------------------------------------------------
3134void Chuck_Instr_Ge_double::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
3135{
3136 t_CKFLOAT *& sp = (t_CKFLOAT *&)shred->reg->sp;
3137 t_CKUINT *& sp_uint = (t_CKUINT *&)sp;
3138 pop_( sp, 2 );
3139 push_( sp_uint, val_(sp) >= val_(sp+1) );
3140}
3141
3142
3143
3144
3145//-----------------------------------------------------------------------------
3146// name: execute()
3147// desc: ...
3148//-----------------------------------------------------------------------------
3149void Chuck_Instr_Eq_double::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
3150{
3151 t_CKFLOAT *& sp = (t_CKFLOAT *&)shred->reg->sp;
3152 t_CKUINT *& sp_uint = (t_CKUINT *&)sp;
3153 pop_( sp, 2 );
3154 push_( sp_uint, val_(sp) == val_(sp+1) );
3155}
3156
3157
3158
3159
3160//-----------------------------------------------------------------------------
3161// name: execute()
3162// desc: ...
3163//-----------------------------------------------------------------------------
3164void Chuck_Instr_Neq_double::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
3165{
3166 t_CKFLOAT *& sp = (t_CKFLOAT *&)shred->reg->sp;
3167 t_CKUINT *& sp_uint = (t_CKUINT *&)sp;
3168 pop_( sp, 2 );
3169 push_( sp_uint, val_(sp) != val_(sp+1) );
3170}
3171
3172
3173
3174//-----------------------------------------------------------------------------
3175// name: execute()
3176// desc: ...
3177//-----------------------------------------------------------------------------
3178void Chuck_Instr_Eq_complex::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
3179{
3180 // also works for polar
3181 t_CKCOMPLEX *& sp = (t_CKCOMPLEX *&)shred->reg->sp;
3182 t_CKUINT *& sp_uint = (t_CKUINT *&)sp;
3183 pop_( sp, 2 );
3184 push_( sp_uint, (sp->re == (sp+1)->re) && (sp->im == (sp+1)->im) );
3185}
3186
3187
3188
3189
3190//-----------------------------------------------------------------------------
3191// name: execute()
3192// desc: ...
3193//-----------------------------------------------------------------------------
3194void Chuck_Instr_Neq_complex::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
3195{
3196 // also works for polar
3197 t_CKCOMPLEX *& sp = (t_CKCOMPLEX *&)shred->reg->sp;
3198 t_CKUINT *& sp_uint = (t_CKUINT *&)sp;
3199 pop_( sp, 2 );
3200 push_( sp_uint, (sp->re != (sp+1)->re) || (sp->im != (sp+1)->im) );
3201}
3202
3203
3204
3205
3206//-----------------------------------------------------------------------------
3207// name: execute()
3208// desc: ...
3209//-----------------------------------------------------------------------------
3210void Chuck_Instr_Eq_vec3::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
3211{
3212 // also works for polar
3213 t_CKVEC3 *& sp = (t_CKVEC3 *&)shred->reg->sp;
3214 t_CKUINT *& sp_uint = (t_CKUINT *&)sp;
3215 pop_( sp, 2 );
3216 push_( sp_uint, (sp->x == (sp+1)->x) && (sp->y == (sp+1)->y)
3217 && (sp->z == (sp+1)->z) );
3218}
3219
3220
3221
3222
3223//-----------------------------------------------------------------------------
3224// name: execute()
3225// desc: ...
3226//-----------------------------------------------------------------------------
3227void Chuck_Instr_Neq_vec3::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
3228{
3229 // also works for polar
3230 t_CKVEC3 *& sp = (t_CKVEC3 *&)shred->reg->sp;
3231 t_CKUINT *& sp_uint = (t_CKUINT *&)sp;
3232 pop_( sp, 2 );
3233 push_( sp_uint, (sp->x != (sp+1)->x) || (sp->y != (sp+1)->y)
3234 || (sp->z != (sp+1)->z) );
3235}
3236
3237
3238
3239
3240//-----------------------------------------------------------------------------
3241// name: execute()
3242// desc: ...
3243//-----------------------------------------------------------------------------
3244void Chuck_Instr_Eq_vec4::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
3245{
3246 // also works for polar
3247 t_CKVEC4 *& sp = (t_CKVEC4 *&)shred->reg->sp;
3248 t_CKUINT *& sp_uint = (t_CKUINT *&)sp;
3249 pop_( sp, 2 );
3250 push_( sp_uint, (sp->x == (sp+1)->x) && (sp->y == (sp+1)->y)
3251 && (sp->z == (sp+1)->z) && (sp->w == (sp+1)->w) );
3252}
3253
3254
3255
3256
3257//-----------------------------------------------------------------------------
3258// name: execute()
3259// desc: ...
3260//-----------------------------------------------------------------------------
3261void Chuck_Instr_Neq_vec4::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
3262{
3263 // also works for polar
3264 t_CKVEC4 *& sp = (t_CKVEC4 *&)shred->reg->sp;
3265 t_CKUINT *& sp_uint = (t_CKUINT *&)sp;
3266 pop_( sp, 2 );
3267 push_( sp_uint, (sp->x != (sp+1)->x) || (sp->y != (sp+1)->y)
3268 || (sp->z != (sp+1)->z) || (sp->w != (sp+1)->w) );
3269}
3270
3271
3272
3273
3274#pragma mark === Boolean Arithmetic ===
3275
3276
3277//-----------------------------------------------------------------------------
3278// name: execute()
3279// desc: ...
3280//-----------------------------------------------------------------------------
3281void Chuck_Instr_And::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
3282{
3283 t_CKUINT *& sp = (t_CKUINT *&)shred->reg->sp;
3284 pop_( sp, 2 );
3285 push_( sp, val_(sp) && val_(sp+1) );
3286}
3287
3288
3289
3290
3291//-----------------------------------------------------------------------------
3292// name: execute()
3293// desc: ...
3294//-----------------------------------------------------------------------------
3295void Chuck_Instr_Or::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
3296{
3297 t_CKUINT *& sp = (t_CKUINT *&)shred->reg->sp;
3298 pop_( sp, 2 );
3299 push_( sp, val_(sp) || val_(sp+1) );
3300}
3301
3302
3303
3304#pragma mark === Miscellany ===
3305
3306
3307//-----------------------------------------------------------------------------
3308// name: execute()
3309// desc: ...
3310//-----------------------------------------------------------------------------
3311void Chuck_Instr_Goto::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
3312{
3313 shred->next_pc = m_jmp;
3314}
3315
3316
3317
3318
3319//-----------------------------------------------------------------------------
3320// name: execute()
3321// desc: ...
3322//-----------------------------------------------------------------------------
3323void Chuck_Instr_Nop::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
3324{
3325 // no op
3326}
3327
3328
3329
3330
3331//-----------------------------------------------------------------------------
3332// name: execute()
3333// desc: ...
3334//-----------------------------------------------------------------------------
3335void Chuck_Instr_EOC::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
3336{
3337 // end the shred
3338 shred->is_done = TRUE;
3339 shred->is_running = FALSE;
3340}
3341
3342
3343
3344#pragma mark === Allocation ===
3345
3346
3347
3348
3349//-----------------------------------------------------------------------------
3350// name: execute()
3351// desc: alloc local
3352//-----------------------------------------------------------------------------
3353void Chuck_Instr_Alloc_Word::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
3354{
3355 t_CKBYTE *& mem_sp = (t_CKBYTE *&)shred->mem->sp;
3356 t_CKUINT *& reg_sp = (t_CKUINT *&)shred->reg->sp;
3357
3358 // zero out the memory stack
3359 *( (t_CKUINT *)(mem_sp + m_val) ) = 0;
3360 // push addr onto operand stack
3361 push_( reg_sp, (t_CKUINT)(mem_sp + m_val) );
3362}
3363
3364
3365
3366
3367//-----------------------------------------------------------------------------
3368// name: execute()
3369// desc: alloc local
3370//-----------------------------------------------------------------------------
3371void Chuck_Instr_Alloc_Word2::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
3372{
3373 t_CKBYTE *& mem_sp = (t_CKBYTE *&)shred->mem->sp;
3374 t_CKUINT *& reg_sp = (t_CKUINT *&)shred->reg->sp;
3375
3376 // zero out the memory stack
3377 *( (t_CKFLOAT *)(mem_sp + m_val) ) = 0.0;
3378 // push addr onto operand stack
3379 push_( reg_sp, (t_CKUINT)(mem_sp + m_val) );
3380}
3381
3382
3383
3384
3385//-----------------------------------------------------------------------------
3386// name: execute()
3387// desc: alloc local
3388//-----------------------------------------------------------------------------
3389void Chuck_Instr_Alloc_Word4::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
3390{
3391 t_CKBYTE *& mem_sp = (t_CKBYTE *&)shred->mem->sp;
3392 t_CKUINT *& reg_sp = (t_CKUINT *&)shred->reg->sp;
3393
3394 // zero out the memory stack
3395 ( (t_CKCOMPLEX *)(mem_sp + m_val) )->re = 0.0;
3396 ( (t_CKCOMPLEX *)(mem_sp + m_val) )->im = 0.0;
3397 // push addr onto operand stack
3398 push_( reg_sp, (t_CKUINT)(mem_sp + m_val) );
3399}
3400
3401
3402
3403
3404//-----------------------------------------------------------------------------
3405// name: execute()
3406// desc: alloc local
3407//-----------------------------------------------------------------------------
3408void Chuck_Instr_Alloc_Vec3::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
3409{
3410 t_CKBYTE *& mem_sp = (t_CKBYTE *&)shred->mem->sp;
3411 t_CKUINT *& reg_sp = (t_CKUINT *&)shred->reg->sp;
3412
3413 // zero out the memory stack
3414 ( (t_CKVEC3 *)(mem_sp + m_val) )->x = 0.0;
3415 ( (t_CKVEC3 *)(mem_sp + m_val) )->y = 0.0;
3416 ( (t_CKVEC3 *)(mem_sp + m_val) )->z = 0.0;
3417 // push addr onto operand stack
3418 push_( reg_sp, (t_CKUINT)(mem_sp + m_val) );
3419}
3420
3421
3422
3423
3424//-----------------------------------------------------------------------------
3425// name: execute()
3426// desc: alloc local
3427//-----------------------------------------------------------------------------
3428void Chuck_Instr_Alloc_Vec4::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
3429{
3430 t_CKBYTE *& mem_sp = (t_CKBYTE *&)shred->mem->sp;
3431 t_CKUINT *& reg_sp = (t_CKUINT *&)shred->reg->sp;
3432
3433 // zero out the memory stack
3434 ( (t_CKVEC4 *)(mem_sp + m_val) )->x = 0.0;
3435 ( (t_CKVEC4 *)(mem_sp + m_val) )->y = 0.0;
3436 ( (t_CKVEC4 *)(mem_sp + m_val) )->z = 0.0;
3437 ( (t_CKVEC4 *)(mem_sp + m_val) )->w = 0.0;
3438 // push addr onto operand stack
3439 push_( reg_sp, (t_CKUINT)(mem_sp + m_val) );
3440}
3441
3442
3443
3444
3445//-----------------------------------------------------------------------------
3446// name: execute()
3447// desc: alloc member
3448//-----------------------------------------------------------------------------
3449void Chuck_Instr_Alloc_Member_Word::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
3450{
3451 t_CKUINT *& mem_sp = (t_CKUINT *&)shred->mem->sp;
3452 t_CKUINT *& reg_sp = (t_CKUINT *&)shred->reg->sp;
3453
3454 // get the object
3455 Chuck_Object * obj = (Chuck_Object *)*(mem_sp);
3456 // zero out the memory stack
3457 *( (t_CKUINT *)(obj->data + m_val) ) = 0;
3458 // push addr onto operand stack
3459 push_( reg_sp, (t_CKUINT)(obj->data + m_val) );
3460}
3461
3462
3463
3464
3465//-----------------------------------------------------------------------------
3466// name: execute()
3467// desc: alloc member
3468//-----------------------------------------------------------------------------
3469void Chuck_Instr_Alloc_Member_Word2::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
3470{
3471 t_CKUINT *& mem_sp = (t_CKUINT *&)shred->mem->sp;
3472 t_CKUINT *& reg_sp = (t_CKUINT *&)shred->reg->sp;
3473
3474 // get the object
3475 Chuck_Object * obj = (Chuck_Object *)*(mem_sp);
3476 // zero out the memory stack
3477 *( (t_CKFLOAT *)(obj->data + m_val) ) = 0.0;
3478 // push addr onto operand stack
3479 push_( reg_sp, (t_CKUINT)(obj->data + m_val) );
3480}
3481
3482
3483
3484
3485//-----------------------------------------------------------------------------
3486// name: execute()
3487// desc: alloc member
3488//-----------------------------------------------------------------------------
3489void Chuck_Instr_Alloc_Member_Word4::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
3490{
3491 t_CKUINT *& mem_sp = (t_CKUINT *&)shred->mem->sp;
3492 t_CKUINT *& reg_sp = (t_CKUINT *&)shred->reg->sp;
3493
3494 // get the object
3495 Chuck_Object * obj = (Chuck_Object *)*(mem_sp);
3496 // zero out the memory stack
3497 ( (t_CKCOMPLEX *)(obj->data + m_val) )->re = 0.0;
3498 ( (t_CKCOMPLEX *)(obj->data + m_val) )->im = 0.0;
3499 // push addr onto operand stack
3500 push_( reg_sp, (t_CKUINT)(obj->data + m_val) );
3501}
3502
3503
3504
3505
3506//-----------------------------------------------------------------------------
3507// name: execute()
3508// desc: alloc member
3509//-----------------------------------------------------------------------------
3510void Chuck_Instr_Alloc_Member_Vec3::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
3511{
3512 t_CKUINT *& mem_sp = (t_CKUINT *&)shred->mem->sp;
3513 t_CKUINT *& reg_sp = (t_CKUINT *&)shred->reg->sp;
3514
3515 // get the object
3516 Chuck_Object * obj = (Chuck_Object *)*(mem_sp);
3517 // zero out the memory stack
3518 ( (t_CKVEC3 *)(obj->data + m_val) )->x = 0.0;
3519 ( (t_CKVEC3 *)(obj->data + m_val) )->y = 0.0;
3520 ( (t_CKVEC3 *)(obj->data + m_val) )->z = 0.0;
3521 // push addr onto operand stack
3522 push_( reg_sp, (t_CKUINT)(obj->data + m_val) );
3523}
3524
3525
3526
3527
3528//-----------------------------------------------------------------------------
3529// name: execute()
3530// desc: alloc member
3531//-----------------------------------------------------------------------------
3532void Chuck_Instr_Alloc_Member_Vec4::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
3533{
3534 t_CKUINT *& mem_sp = (t_CKUINT *&)shred->mem->sp;
3535 t_CKUINT *& reg_sp = (t_CKUINT *&)shred->reg->sp;
3536
3537 // get the object
3538 Chuck_Object * obj = (Chuck_Object *)*(mem_sp);
3539 // zero out the memory stack
3540 ( (t_CKVEC4 *)(obj->data + m_val) )->x = 0.0;
3541 ( (t_CKVEC4 *)(obj->data + m_val) )->y = 0.0;
3542 ( (t_CKVEC4 *)(obj->data + m_val) )->z = 0.0;
3543 ( (t_CKVEC4 *)(obj->data + m_val) )->w = 0.0;
3544 // push addr onto operand stack
3545 push_( reg_sp, (t_CKUINT)(obj->data + m_val) );
3546}
3547
3548
3549
3550
3551//-----------------------------------------------------------------------------
3552// name: execute()
3553// desc: alloc external
3554//-----------------------------------------------------------------------------
3555void Chuck_Instr_Alloc_Word_External::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
3556{
3557 t_CKUINT *& reg_sp = (t_CKUINT *&)shred->reg->sp;
3558 t_CKUINT addr = 0;
3559
3560 // init in the correct vm map according to the type
3561 switch( m_type ) {
3562 case te_externalInt:
3563 vm->init_external_int( m_name );
3564 addr = (t_CKUINT) vm->get_ptr_to_external_int( m_name );
3565 break;
3566 case te_externalFloat:
3567 vm->init_external_float( m_name );
3568 addr = (t_CKUINT) vm->get_ptr_to_external_float( m_name );
3569 break;
3570 case te_externalEvent:
3571 // no need to init, it has already been initted during emit
3572 addr = (t_CKUINT) vm->get_ptr_to_external_event( m_name );
3573 break;
3574 }
3575
3576 // push addr onto operand stack
3577 push_( reg_sp, addr );
3578}
3579
3580
3581
3582
3583#pragma mark === Object Initialization/Construction ===
3584
3585
3586static Chuck_Instr_Func_Call g_func_call;
3587static Chuck_Instr_Func_Call_Member g_func_call_member( 0 );
3588//-----------------------------------------------------------------------------
3589// name: call_pre_constructor()
3590// desc: ...
3591//-----------------------------------------------------------------------------
3592inline void call_pre_constructor( Chuck_VM * vm, Chuck_VM_Shred * shred,
3593 Chuck_VM_Code * pre_ctor, t_CKUINT stack_offset )
3594{
3595 t_CKUINT *& reg_sp = (t_CKUINT *&)shred->reg->sp;
3596
3597 // sanity
3598 assert( pre_ctor != NULL );
3599
3600 // first duplicate the top of the stack, which should be object pointer
3601 push_( reg_sp, *(reg_sp-1) );
3602 // push the pre constructor
3603 push_( reg_sp, (t_CKUINT)pre_ctor );
3604 // push the stack offset
3605 push_( reg_sp, stack_offset );
3606
3607 // call the function
3608 if( pre_ctor->native_func != 0 )
3609 g_func_call_member.execute( vm, shred );
3610 else
3611 g_func_call.execute( vm, shred );
3612}
3613
3614
3615
3616
3617//-----------------------------------------------------------------------------
3618// name: execute()
3619// desc: object pre construct
3620//-----------------------------------------------------------------------------
3621void Chuck_Instr_Pre_Constructor::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
3622{
3623 call_pre_constructor( vm, shred, pre_ctor, stack_offset );
3624}
3625
3626
3627
3628
3629//-----------------------------------------------------------------------------
3630// name: instantiate_object()
3631// desc: ...
3632//-----------------------------------------------------------------------------
3633t_CKBOOL initialize_object( Chuck_Object * object, Chuck_Type * type )
3634{
3635 // sanity
3636 assert( type != NULL );
3637 assert( type->info != NULL );
3638
3639 // allocate virtual table
3640 object->vtable = new Chuck_VTable;
3641 if( !object->vtable ) goto out_of_memory;
3642 // copy the object's virtual table
3643 object->vtable->funcs = type->info->obj_v_table.funcs;
3644 // set the type reference
3645 // TODO: reference count
3646 object->type_ref = type;
3647 object->type_ref->add_ref();
3648 // get the size
3649 object->size = type->obj_size;
3650 // allocate memory
3651 if( object->size )
3652 {
3653 // check to ensure enough memory
3654 object->data = new t_CKBYTE[object->size];
3655 if( !object->data ) goto out_of_memory;
3656 // zero it out
3657 memset( object->data, 0, object->size );
3658 }
3659 else object->data = NULL;
3660
3661 // special
3662 if( type->ugen_info )
3663 {
3664 // ugen
3665 Chuck_UGen * ugen = (Chuck_UGen *)object;
3666 if( type->ugen_info->tick ) ugen->tick = type->ugen_info->tick;
3667 // added 1.3.0.0 -- tickf for multi-channel tick
3668 if( type->ugen_info->tickf ) ugen->tickf = type->ugen_info->tickf;
3669 if( type->ugen_info->pmsg ) ugen->pmsg = type->ugen_info->pmsg;
3670 // TODO: another hack!
3671 if( type->ugen_info->tock ) ((Chuck_UAna *)ugen)->tock = type->ugen_info->tock;
3672 // allocate multi chan
3673 ugen->alloc_multi_chan( type->ugen_info->num_ins,
3674 type->ugen_info->num_outs );
3675 // allocate the channels
3676 for( t_CKUINT i = 0; i < ugen->m_multi_chan_size; i++ )
3677 {
3678 // allocate ugen for each | REFACTOR-2017: added ugen->vm
3679 Chuck_Object * obj = instantiate_and_initialize_object(
3680 ugen->vm->env()->t_ugen, ugen->shred, ugen->vm );
3681 // cast to ugen
3682 ugen->m_multi_chan[i] = (Chuck_UGen *)obj;
3683 // additional reference count
3684 ugen->m_multi_chan[i]->add_ref();
3685 // owner
3686 ugen->m_multi_chan[i]->owner = ugen;
3687 // ref count
3688 // spencer 2013-5-20: don't add extra ref, to avoid a ref cycle
3689 //ugen->add_ref();
3690 }
3691 // TODO: alloc channels for uana
3692 }
3693
3694 return TRUE;
3695
3696out_of_memory:
3697
3698 // we have a problem
3699 CK_FPRINTF_STDERR(
3700 "[chuck](VM): OutOfMemory: while instantiating object '%s'\n",
3701 type->c_name() );
3702
3703 // delete
3704 if( object ) SAFE_DELETE( object->vtable );
3705
3706 // return FALSE
3707 return FALSE;
3708}
3709
3710
3711
3712
3713//-----------------------------------------------------------------------------
3714// name: instantiate_and_initialize_object()
3715// desc: call this one if you have a non-null shred
3716//-----------------------------------------------------------------------------
3717Chuck_Object * instantiate_and_initialize_object( Chuck_Type * type, Chuck_VM_Shred * shred )
3718{
3719 assert( shred != NULL );
3720 return instantiate_and_initialize_object( type, shred, shred->vm_ref );
3721}
3722
3723
3724
3725
3726//-----------------------------------------------------------------------------
3727// name: instantiate_and_initialize_object()
3728// desc: call this one if you don't have a shred
3729//-----------------------------------------------------------------------------
3730Chuck_Object * instantiate_and_initialize_object( Chuck_Type * type, Chuck_VM * vm )
3731{
3732 assert( vm != NULL );
3733 return instantiate_and_initialize_object( type, NULL, vm );
3734}
3735
3736
3737
3738
3739//-----------------------------------------------------------------------------
3740// name: instantiate_and_initialize_object()
3741// desc: you probably shouldn't call this version. call the one that takes a
3742// shred if you have a non-null shred, otherwise call the one that
3743// takes a vm
3744//-----------------------------------------------------------------------------
3745Chuck_Object * instantiate_and_initialize_object( Chuck_Type * type, Chuck_VM_Shred * shred, Chuck_VM * vm )
3746{
3747 Chuck_Object * object = NULL;
3748 Chuck_UAna * uana = NULL;
3749
3750 // sanity
3751 assert( type != NULL );
3752 assert( type->info != NULL );
3753
3754 // allocate the VM object
3755 if( !type->ugen_info )
3756 {
3757 // check type TODO: make this faster
3758 if( type->allocator )
3759 object = type->allocator( shred, Chuck_DL_Api::Api::instance() );
3760 else if( isa( type, vm->env()->t_fileio ) ) object = new Chuck_IO_File( vm );
3761 else if( isa( type, vm->env()->t_event ) ) object = new Chuck_Event;
3762 else if( isa( type, vm->env()->t_string ) ) object = new Chuck_String;
3763 // TODO: is this ok?
3764 else if( isa( type, vm->env()->t_shred ) )
3765 {
3766 object = new Chuck_VM_Shred;
3767 ((Chuck_VM_Shred * )object)->vm_ref = vm; // REFACTOR-2017
3768 }
3769 // TODO: is this ok?
3770 else object = new Chuck_Object;
3771 }
3772 else
3773 {
3774 // make ugen
3775 Chuck_UGen * ugen = NULL;
3776 // ugen vs. uana
3777 if( type->ugen_info->tock != NULL )
3778 {
3779 // uana
3780 object = ugen = uana = new Chuck_UAna;
3781 ugen->alloc_v( vm->shreduler()->m_max_block_size );
3782 }
3783 else
3784 {
3785 object = ugen = new Chuck_UGen;
3786 ugen->alloc_v( vm->shreduler()->m_max_block_size );
3787 }
3788
3789 if( shred )
3790 {
3791 ugen->shred = shred;
3792 shred->add( ugen );
3793 }
3794
3795 // REFACTOR-2017: added
3796 ugen->vm = vm;
3797 }
3798
3799 // check to see enough memory
3800 if( !object ) goto out_of_memory;
3801
3802 // initialize
3803 if( !initialize_object( object, type ) ) goto error;
3804
3805 return object;
3806
3807out_of_memory:
3808
3809 // we have a problem
3810 CK_FPRINTF_STDERR(
3811 "[chuck](VM): OutOfMemory: while instantiating object '%s'\n",
3812 type->c_name() );
3813
3814error:
3815
3816 // delete
3817 SAFE_DELETE( object );
3818
3819 // return NULL
3820 return NULL;
3821}
3822
3823
3824
3825
3826//-----------------------------------------------------------------------------
3827// name: instantiate_object()
3828// desc: ...
3829//-----------------------------------------------------------------------------
3830inline void instantiate_object( Chuck_VM * vm, Chuck_VM_Shred * shred,
3831 Chuck_Type * type )
3832{
3833 t_CKUINT *& reg_sp = (t_CKUINT *&)shred->reg->sp;
3834
3835 // allocate the VM object
3836 Chuck_Object * object = instantiate_and_initialize_object( type, shred );
3837 if( !object ) goto error;
3838
3839 // push the pointer on the operand stack
3840 push_( reg_sp, (t_CKUINT)object );
3841
3842 // call preconstructor
3843 // call_pre_constructor( vm, shred, object, type, stack_offset );
3844
3845 return;
3846
3847error:
3848
3849 // do something!
3850 shred->is_running = FALSE;
3851 shred->is_done = TRUE;
3852}
3853
3854
3855
3856
3857//-----------------------------------------------------------------------------
3858// name: execute()
3859// desc: instantiate object
3860//-----------------------------------------------------------------------------
3861void Chuck_Instr_Instantiate_Object::execute( Chuck_VM * vm, Chuck_VM_Shred * shred )
3862{
3863 instantiate_object( vm, shred, this->type );
3864}
3865
3866
3867
3868
3869//-----------------------------------------------------------------------------
3870// name: params()
3871// desc: ...
3872//-----------------------------------------------------------------------------
3873const char * Chuck_Instr_Instantiate_Object::params() const
3874{
3875 static char buffer[256];
3876 sprintf( buffer, "%s", this->type->c_name() );
3877 return buffer;
3878}
3879
3880
3881
3882
3883//-----------------------------------------------------------------------------
3884// name: params()
3885// desc: text description
3886//-----------------------------------------------------------------------------
3887const char * Chuck_Instr_Pre_Ctor_Array_Top::params() const
3888{
3889 static char buffer[256];
3890 sprintf( buffer, "val=%ld, type=\"%s\"", m_val, type ? type->c_name() : "[empty]" );
3891 return buffer;
3892}
3893
3894
3895
3896
3897//-----------------------------------------------------------------------------
3898// name: execute()
3899// desc: object pre construct top
3900//-----------------------------------------------------------------------------

3590 more lines aren’t shown here.

core/chuck_instr.h+0−4047

This diff is large: its 4048 lines aren’t shown here.

core/chuck_io.cpp+0−1949

This diff is large: its 1950 lines aren’t shown here.

core/chuck_io.h+0−204

This diff is large: its 205 lines aren’t shown here.

core/chuck_lang.cpp+0−4860

This diff is large: its 4861 lines aren’t shown here.

core/chuck_lang.h+0−481

This diff is large: its 482 lines aren’t shown here.

core/chuck_oo.cpp+0−3285

This diff is large: its 3286 lines aren’t shown here.

core/chuck_oo.h+0−708

This diff is large: its 709 lines aren’t shown here.

core/chuck_otf.cpp+0−747

This diff is large: its 748 lines aren’t shown here.

core/chuck_otf.h+0−101

This diff is large: its 102 lines aren’t shown here.

core/chuck_parse.cpp+0−230

This diff is large: its 231 lines aren’t shown here.

core/chuck_parse.h+0−153

This diff is large: its 154 lines aren’t shown here.

core/chuck_scan.cpp+0−2732

This diff is large: its 2733 lines aren’t shown here.

core/chuck_scan.h+0−71

This diff is large: its 72 lines aren’t shown here.

core/chuck_shell.cpp+0−2260

This diff is large: its 2261 lines aren’t shown here.

core/chuck_shell.h+0−578

This diff is large: its 579 lines aren’t shown here.

core/chuck_stats.cpp+0−302

This diff is large: its 303 lines aren’t shown here.

core/chuck_stats.h+0−198

This diff is large: its 199 lines aren’t shown here.

core/chuck_symbol.cpp+0−143

This diff is large: its 144 lines aren’t shown here.

core/chuck_symbol.h+0−88

This diff is large: its 89 lines aren’t shown here.

core/chuck_table.cpp+0−221

This diff is large: its 222 lines aren’t shown here.

core/chuck_table.h+0−76

This diff is large: its 77 lines aren’t shown here.

core/chuck_type.cpp+0−6488

This diff is large: its 6489 lines aren’t shown here.

core/chuck_type.h+0−970

This diff is large: its 971 lines aren’t shown here.

core/chuck_ugen.cpp+0−1543

This diff is large: its 1544 lines aren’t shown here.

core/chuck_ugen.h+0−199

This diff is large: its 200 lines aren’t shown here.

core/chuck_utils.cpp+0−77

This diff is large: its 78 lines aren’t shown here.

core/chuck_utils.h+0−62

This diff is large: its 63 lines aren’t shown here.

core/chuck_vm.cpp+0−2760

This diff is large: its 2761 lines aren’t shown here.

core/chuck_vm.h+0−755

This diff is large: its 756 lines aren’t shown here.

core/chuck_win32.c+0−2632

This diff is large: its 2633 lines aren’t shown here.

core/chuck_win32.h+0−203

This diff is large: its 204 lines aren’t shown here.

core/dirent_win32.h+0−234

This diff is large: its 235 lines aren’t shown here.

core/hidio_sdl.cpp+0−1032

This diff is large: its 1033 lines aren’t shown here.

core/hidio_sdl.h+0−172

This diff is large: its 173 lines aren’t shown here.

core/lo/address.c+0−346

This diff is large: its 347 lines aren’t shown here.

core/lo/blob.c+0−64

This diff is large: its 65 lines aren’t shown here.

core/lo/bundle.c+0−181

This diff is large: its 182 lines aren’t shown here.

core/lo/config.h+0−200

This diff is large: its 201 lines aren’t shown here.

core/lo/lo.h+0−353

This diff is large: its 354 lines aren’t shown here.

core/lo/lo_endian.h+0−256

This diff is large: its 257 lines aren’t shown here.

core/lo/lo_errors.h+0−45

This diff is large: its 46 lines aren’t shown here.

core/lo/lo_internal.h+0−63

This diff is large: its 64 lines aren’t shown here.

core/lo/lo_lowlevel.h+0−860

This diff is large: its 861 lines aren’t shown here.

core/lo/lo_macros.h+0−80

This diff is large: its 81 lines aren’t shown here.

core/lo/lo_osc_types.h+0−145

This diff is large: its 146 lines aren’t shown here.

core/lo/lo_throw.h+0−30

This diff is large: its 31 lines aren’t shown here.

core/lo/lo_types.h+0−143

This diff is large: its 144 lines aren’t shown here.

core/lo/lo_types_internal.h+0−145

This diff is large: its 146 lines aren’t shown here.

core/lo/message.c+0−1081

This diff is large: its 1082 lines aren’t shown here.

core/lo/method.c+0−35

This diff is large: its 36 lines aren’t shown here.

core/lo/pattern_match.c+0−248

This diff is large: its 249 lines aren’t shown here.

core/lo/send.c+0−491

This diff is large: its 492 lines aren’t shown here.

core/lo/server.c+0−1400

This diff is large: its 1401 lines aren’t shown here.

core/lo/server_thread.c+0−188

This diff is large: its 189 lines aren’t shown here.

core/lo/timetag.c+0−58

This diff is large: its 59 lines aren’t shown here.

core/midiio_rtmidi.cpp+0−1010

This diff is large: its 1011 lines aren’t shown here.

core/midiio_rtmidi.h+0−278

This diff is large: its 279 lines aren’t shown here.

core/regex/LICENSE.txt+0−29

This diff is large: its 30 lines aren’t shown here.

core/regex/README.txt+0−235

This diff is large: its 236 lines aren’t shown here.

core/regex/config.h+0−184

This diff is large: its 185 lines aren’t shown here.

core/regex/regcomp.c+0−129

This diff is large: its 130 lines aren’t shown here.

core/regex/regerror.c+0−83

This diff is large: its 84 lines aren’t shown here.

core/regex/regex.h+0−38

This diff is large: its 39 lines aren’t shown here.

core/regex/regexec.c+0−348

This diff is large: its 349 lines aren’t shown here.

core/regex/tre-ast.c+0−226

This diff is large: its 227 lines aren’t shown here.

core/regex/tre-ast.h+0−128

This diff is large: its 129 lines aren’t shown here.

core/regex/tre-compile.c+0−2296

This diff is large: its 2297 lines aren’t shown here.

core/regex/tre-compile.h+0−27

This diff is large: its 28 lines aren’t shown here.

core/regex/tre-config.h+0−52

This diff is large: its 53 lines aren’t shown here.

core/regex/tre-filter.c+0−73

This diff is large: its 74 lines aren’t shown here.

core/regex/tre-filter.h+0−19

This diff is large: its 20 lines aren’t shown here.

core/regex/tre-internal.h+0−287

This diff is large: its 288 lines aren’t shown here.

core/regex/tre-match-approx.c+0−812

This diff is large: its 813 lines aren’t shown here.

core/regex/tre-match-backtrack.c+0−666

This diff is large: its 667 lines aren’t shown here.

core/regex/tre-match-parallel.c+0−501

This diff is large: its 502 lines aren’t shown here.

core/regex/tre-match-utils.h+0−215

This diff is large: its 216 lines aren’t shown here.

core/regex/tre-mem.c+0−155

This diff is large: its 156 lines aren’t shown here.

core/regex/tre-mem.h+0−66

This diff is large: its 67 lines aren’t shown here.

core/regex/tre-parse.c+0−1739

This diff is large: its 1740 lines aren’t shown here.

core/regex/tre-parse.h+0−50

This diff is large: its 51 lines aren’t shown here.

core/regex/tre-stack.c+0−125

This diff is large: its 126 lines aren’t shown here.

core/regex/tre-stack.h+0−76

This diff is large: its 77 lines aren’t shown here.

core/regex/tre.h+0−276

This diff is large: its 277 lines aren’t shown here.

core/regex/xmalloc.c+0−351

This diff is large: its 352 lines aren’t shown here.

core/regex/xmalloc.h+0−77

This diff is large: its 78 lines aren’t shown here.

core/rtmidi.cpp+0−2322

This diff is large: its 2323 lines aren’t shown here.

core/rtmidi.h+0−362

This diff is large: its 363 lines aren’t shown here.

core/uana_extract.cpp+0−1526

This diff is large: its 1527 lines aren’t shown here.

core/uana_extract.h+0−45

This diff is large: its 46 lines aren’t shown here.

core/uana_xform.cpp+0−3762

This diff is large: its 3763 lines aren’t shown here.

core/uana_xform.h+0−45

This diff is large: its 46 lines aren’t shown here.

core/ugen_filter.cpp+0−2694

This diff is large: its 2695 lines aren’t shown here.

core/ugen_filter.h+0−238

This diff is large: its 239 lines aren’t shown here.

core/ugen_osc.cpp+0−1759

This diff is large: its 1760 lines aren’t shown here.

core/ugen_osc.h+0−112

This diff is large: its 113 lines aren’t shown here.

core/ugen_stk.cpp+0−27019

This diff is large: its 27020 lines aren’t shown here.

core/ugen_stk.h+0−6622

This diff is large: its 6623 lines aren’t shown here.

core/ugen_xxx.cpp+0−4964

This diff is large: its 4965 lines aren’t shown here.

core/ugen_xxx.h+0−256

This diff is large: its 257 lines aren’t shown here.

core/ulib_machine.cpp+0−220

This diff is large: its 221 lines aren’t shown here.

core/ulib_machine.h+0−62

This diff is large: its 63 lines aren’t shown here.

core/ulib_math.cpp+0−777

This diff is large: its 778 lines aren’t shown here.

core/ulib_math.h+0−100

This diff is large: its 101 lines aren’t shown here.

core/ulib_opsc.cpp+0−1662

This diff is large: its 1663 lines aren’t shown here.

core/ulib_opsc.h+0−79

This diff is large: its 80 lines aren’t shown here.

core/ulib_regex.cpp+0−404

This diff is large: its 405 lines aren’t shown here.

core/ulib_regex.h+0−40

This diff is large: its 41 lines aren’t shown here.

core/ulib_std.cpp+0−1985

This diff is large: its 1986 lines aren’t shown here.

core/ulib_std.h+0−143

This diff is large: its 144 lines aren’t shown here.

core/util_buffers.cpp+0−1022

This diff is large: its 1023 lines aren’t shown here.

core/util_buffers.h+0−698

This diff is large: its 699 lines aren’t shown here.

core/util_console.cpp+0−210

This diff is large: its 211 lines aren’t shown here.

core/util_console.h+0−51

This diff is large: its 52 lines aren’t shown here.

core/util_hid.cpp+0−8068

This diff is large: its 8069 lines aren’t shown here.

core/util_hid.h+0−221

This diff is large: its 222 lines aren’t shown here.

core/util_math.c+0−200

This diff is large: its 201 lines aren’t shown here.

core/util_math.h+0−75

This diff is large: its 76 lines aren’t shown here.

core/util_network.c+0−442

This diff is large: its 443 lines aren’t shown here.

core/util_network.h+0−105

This diff is large: its 106 lines aren’t shown here.

core/util_opsc.cpp+0−2540

This diff is large: its 2541 lines aren’t shown here.

core/util_opsc.h+0−630

This diff is large: its 631 lines aren’t shown here.

core/util_raw.c+0−4784

This diff is large: its 4785 lines aren’t shown here.

core/util_raw.h+0−100

This diff is large: its 101 lines aren’t shown here.

core/util_serial.cpp+0−248

This diff is large: its 249 lines aren’t shown here.

core/util_serial.h+0−58

This diff is large: its 59 lines aren’t shown here.

core/util_sndfile.c+0−34323

This diff is large: its 34324 lines aren’t shown here.

core/util_sndfile.h+0−2706

This diff is large: its 2707 lines aren’t shown here.

core/util_string.cpp+0−569

This diff is large: its 570 lines aren’t shown here.

core/util_string.h+0−87

This diff is large: its 88 lines aren’t shown here.

core/util_thread.cpp+0−523

This diff is large: its 524 lines aren’t shown here.

core/util_thread.h+0−233

This diff is large: its 234 lines aren’t shown here.

core/util_xforms.c+0−454

This diff is large: its 455 lines aren’t shown here.

core/util_xforms.h+0−89

This diff is large: its 90 lines aren’t shown here.

src/scripts/compressSndFile.plrenamed from scripts/compressSndFile.pl+0−0

File renamed without changes.

src/scripts/hex2cpp.cpprenamed from scripts/hex2cpp.cpp+0−0

File renamed without changes.

src/scripts/platform.cpprenamed from scripts/platform.cpp+0−0

File renamed without changes.

src/scripts/raw2code.cpprenamed from scripts/raw2code.cpp+0−0

File renamed without changes.

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t