Unified · Split
| @@ -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 | ||
| 62 | const char ChucK::VERSION[] = "1.3.6.0-rc1 (numchuck)"; | ||
| 63 | t_CKUINT ChucK::o_numVMs = 0; | ||
| 64 | |||
| 65 | |||
| 66 | |||
| 67 | |||
| 68 | //----------------------------------------------------------------------------- | ||
| 69 | // name: version() | ||
| 70 | // desc: get chuck version | ||
| 71 | //----------------------------------------------------------------------------- | ||
| 72 | const 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 | //----------------------------------------------------------------------------- | ||
| 84 | t_CKUINT ChucK::intSize() | ||
| 85 | { | ||
| 86 | return machine_intsize(); | ||
| 87 | } | ||
| 88 | |||
| 89 | |||
| 90 | |||
| 91 | |||
| 92 | //----------------------------------------------------------------------------- | ||
| 93 | // name: ChucK() | ||
| 94 | // desc: constructor | ||
| 95 | //----------------------------------------------------------------------------- | ||
| 96 | ChucK::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 | //----------------------------------------------------------------------------- | ||
| 115 | ChucK::~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 | //----------------------------------------------------------------------------- | ||
| 131 | enum 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 | //----------------------------------------------------------------------------- | ||
| 142 | std::map< std::string, ck_param_type> ck_param_types; | ||
| 143 | |||
| 144 | |||
| 145 | |||
| 146 | |||
| 147 | //----------------------------------------------------------------------------- | ||
| 148 | // name: initDefaultParams() | ||
| 149 | // desc: initialize default params | ||
| 150 | //----------------------------------------------------------------------------- | ||
| 151 | void 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 | //----------------------------------------------------------------------------- | ||
| 183 | bool 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 | //----------------------------------------------------------------------------- | ||
| 205 | bool 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 | //----------------------------------------------------------------------------- | ||
| 227 | bool 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 | //----------------------------------------------------------------------------- | ||
| 247 | t_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 | //----------------------------------------------------------------------------- | ||
| 265 | t_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 | //----------------------------------------------------------------------------- | ||
| 283 | std::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 | //----------------------------------------------------------------------------- | ||
| 301 | bool 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 | |||
| 384 | cleanup: | ||
| 385 | // shutdown, dealloc | ||
| 386 | shutdown(); | ||
| 387 | |||
| 388 | return false; | ||
| 389 | } | ||
| 390 | |||
| 391 | |||
| 392 | |||
| 393 | |||
| 394 | //----------------------------------------------------------------------------- | ||
| 395 | // shutdown ChucK | ||
| 396 | //----------------------------------------------------------------------------- | ||
| 397 | bool 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 | //----------------------------------------------------------------------------- | ||
| 437 | bool 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 | //----------------------------------------------------------------------------- | ||
| 508 | bool 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 | //----------------------------------------------------------------------------- | ||
| 581 | bool 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 | //----------------------------------------------------------------------------- | ||
| 604 | void 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 | //----------------------------------------------------------------------------- | ||
| 620 | t_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 | //----------------------------------------------------------------------------- | ||
| 633 | t_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 | //----------------------------------------------------------------------------- | ||
| 646 | t_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 | //----------------------------------------------------------------------------- | ||
| 659 | t_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 | //----------------------------------------------------------------------------- | ||
| 672 | t_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 | //----------------------------------------------------------------------------- | ||
| 685 | t_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 | //----------------------------------------------------------------------------- | ||
| 698 | t_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 | //----------------------------------------------------------------------------- | ||
| 712 | t_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 | //----------------------------------------------------------------------------- | ||
| 726 | t_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 | //----------------------------------------------------------------------------- | ||
| 739 | t_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 | //----------------------------------------------------------------------------- | ||
| 752 | void 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 | //----------------------------------------------------------------------------- | ||
| 765 | void ChucK::poop() | ||
| 766 | { | ||
| 767 | ::uh(); | ||
| 768 | } | ||
| @@ -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 | //----------------------------------------------------------------------------- | ||
| 72 | class ChucK | ||
| 73 | { | ||
| 74 | public: | ||
| 75 | // constructor | ||
| 76 | ChucK(); | ||
| 77 | // desctructor | ||
| 78 | virtual ~ChucK(); | ||
| 79 | |||
| 80 | public: | ||
| 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 | |||
| 91 | public: | ||
| 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 | |||
| 97 | public: | ||
| 98 | // initialize ChucK (using params) | ||
| 99 | bool init(); | ||
| 100 | // explicit start (optionally -- done as neede from run()) | ||
| 101 | bool start(); | ||
| 102 | |||
| 103 | public: | ||
| 104 | // run engine (call from callback) | ||
| 105 | void run( SAMPLE * input, SAMPLE * output, int numFrames ); | ||
| 106 | |||
| 107 | public: | ||
| 108 | // additional native chuck bindings/types (use with extra caution) | ||
| 109 | bool bind( f_ck_query queryFunc, const std::string & name ); | ||
| 110 | |||
| 111 | public: | ||
| 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 | |||
| 117 | public: | ||
| 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 | |||
| 126 | public: | ||
| 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 | |||
| 133 | public: | ||
| 134 | // TODO Ge: name choice? should this exist? | ||
| 135 | static void finalCleanup(); | ||
| 136 | |||
| 137 | protected: | ||
| 138 | // shutdown | ||
| 139 | bool shutdown(); | ||
| 140 | |||
| 141 | public: // 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 | |||
| 151 | protected: | ||
| 152 | // chuck version | ||
| 153 | static const char VERSION[]; | ||
| 154 | // number of VMs -- managed from VM constructor/destructors | ||
| 155 | static t_CKUINT o_numVMs; | ||
| 156 | |||
| 157 | protected: | ||
| 158 | // initialize default params | ||
| 159 | void initDefaultParams(); | ||
| 160 | |||
| 161 | protected: | ||
| 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 | ||
| @@ -1,328 +0,0 @@ | |||
| 1 | |||
| 2 | |||
| 3 | D [0-9] | ||
| 4 | L [a-zA-Z_] | ||
| 5 | H [a-fA-F0-9] | ||
| 6 | E [Ee][+-]?{D}+ | ||
| 7 | FS (f|F|l|L) | ||
| 8 | IS (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 | ||
| 62 | extern YYSTYPE yylval; | ||
| 63 | int 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) | ||
| 69 | extern "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() | ||
| 85 | int yywrap( void ) | ||
| 86 | { | ||
| 87 | char_pos = 1; | ||
| 88 | return 1; | ||
| 89 | } | ||
| 90 | |||
| 91 | // adjust() | ||
| 92 | void adjust() | ||
| 93 | { | ||
| 94 | EM_tokPos = char_pos; | ||
| 95 | char_pos += yyleng; | ||
| 96 | } | ||
| 97 | |||
| 98 | // strip | ||
| 99 | c_str strip_lit( c_str str ) | ||
| 100 | { | ||
| 101 | str[strlen(str)-1] = '\0'; | ||
| 102 | return str+1; | ||
| 103 | } | ||
| 104 | |||
| 105 | // alloc_str() | ||
| 106 | c_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 | ||
| 115 | long 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; } | ||
| 224 | for { adjust(); return FOR; } | ||
| 225 | while { adjust(); return WHILE; } | ||
| 226 | until { adjust(); return UNTIL; } | ||
| 227 | repeat { adjust(); return LOOP; } | ||
| 228 | continue { adjust(); return CONTINUE; } | ||
| 229 | break { adjust(); return BREAK; } | ||
| 230 | if { adjust(); return IF; } | ||
| 231 | else { adjust(); return ELSE; } | ||
| 232 | do { adjust(); return DO; } | ||
| 233 | "<<<" { adjust(); return L_HACK; } | ||
| 234 | ">>>" { adjust(); return R_HACK; } | ||
| 235 | |||
| 236 | return { adjust(); return RETURN; } | ||
| 237 | |||
| 238 | function { adjust(); return FUNCTION; } | ||
| 239 | fun { adjust(); return FUNCTION; } | ||
| 240 | new { adjust(); return NEW; } | ||
| 241 | class { adjust(); return CLASS; } | ||
| 242 | interface { adjust(); return INTERFACE; } | ||
| 243 | extends { adjust(); return EXTENDS; } | ||
| 244 | implements { adjust(); return IMPLEMENTS; } | ||
| 245 | public { adjust(); return PUBLIC; } | ||
| 246 | protected { adjust(); return PROTECTED; } | ||
| 247 | private { adjust(); return PRIVATE; } | ||
| 248 | static { adjust(); return STATIC; } | ||
| 249 | pure { adjust(); return ABSTRACT; } | ||
| 250 | const { adjust(); return CONST; } | ||
| 251 | spork { adjust(); return SPORK; } | ||
| 252 | typeof { 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 | |||
| 274 | 0[xX][0-9a-fA-F]+{IS}? { adjust(); yylval.ival=htol(yytext); return NUM; } | ||
| 275 | 0[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 | ||
| 289 | int 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 | ||
| 304 | int block_comment() | ||
| 305 | { | ||
| 306 | char c, c1; | ||
| 307 | |||
| 308 | loop: | ||
| 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 | */ | ||
| @@ -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 | ||
| 111 | int yylex( void ); | ||
| 112 | |||
| 113 | void yyerror( char *s ) | ||
| 114 | { | ||
| 115 | EM_error( EM_tokPos, "%s", s ); | ||
| 116 | } | ||
| 117 | |||
| 118 | a_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 | ||
| 148 | extern 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 | |||
| 270 | union 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 | |||
| 301 | typedef union YYSTYPE YYSTYPE; | ||
| 302 | # define YYSTYPE_IS_TRIVIAL 1 | ||
| 303 | # define YYSTYPE_IS_DECLARED 1 | ||
| 304 | #endif | ||
| 305 | |||
| 306 | |||
| 307 | extern YYSTYPE yylval; | ||
| 308 | |||
| 309 | int 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 | ||
| 322 | typedef YYTYPE_UINT8 yytype_uint8; | ||
| 323 | #else | ||
| 324 | typedef unsigned char yytype_uint8; | ||
| 325 | #endif | ||
| 326 | |||
| 327 | #ifdef YYTYPE_INT8 | ||
| 328 | typedef YYTYPE_INT8 yytype_int8; | ||
| 329 | #else | ||
| 330 | typedef signed char yytype_int8; | ||
| 331 | #endif | ||
| 332 | |||
| 333 | #ifdef YYTYPE_UINT16 | ||
| 334 | typedef YYTYPE_UINT16 yytype_uint16; | ||
| 335 | #else | ||
| 336 | typedef unsigned short int yytype_uint16; | ||
| 337 | #endif | ||
| 338 | |||
| 339 | #ifdef YYTYPE_INT16 | ||
| 340 | typedef YYTYPE_INT16 yytype_int16; | ||
| 341 | #else | ||
| 342 | typedef 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 | ||
| 481 | void *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 | ||
| 487 | void 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. */ | ||
| 499 | union 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. */ | ||
| 578 | static 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. */ | ||
| 621 | static 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. */ | ||
| 648 | static 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). */ | ||
| 689 | static 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. */ | ||
| 718 | static 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. */ | ||
| 757 | static 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]. */ | ||
| 794 | static 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]. */ | ||
| 805 | static 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. */ | ||
| 818 | static 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 | |||
| 943 | static 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. */ | ||
| 1070 | static 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. */ | ||
| 1107 | static 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. */ | ||
| 1131 | static 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) \ | ||
| 1168 | do \ | ||
| 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 | } \ | ||
| 1182 | while (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) \ | ||
| 1199 | do { \ | ||
| 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) \ | ||
| 1211 | do { \ | ||
| 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 | |||
| 1226 | static void | ||
| 1227 | yy_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 | |||
| 1245 | static void | ||
| 1246 | yy_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 | |||
| 1260 | static void | ||
| 1261 | yy_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) \ | ||
| 1273 | do { \ | ||
| 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 | |||
| 1283 | static void | ||
| 1284 | yy_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) \ | ||
| 1304 | do { \ | ||
| 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. */ | ||
| 1311 | int 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. */ | ||
| 1344 | static YYSIZE_T | ||
| 1345 | yystrlen (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. */ | ||
| 1361 | static char * | ||
| 1362 | yystpcpy (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. */ | ||
| 1383 | static YYSIZE_T | ||
| 1384 | yytnamerr (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. */ | ||
| 1431 | static int | ||
| 1432 | yysyntax_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 | |||
| 1563 | static void | ||
| 1564 | yydestruct (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. */ | ||
| 1580 | int yychar; | ||
| 1581 | |||
| 1582 | /* The semantic value of the lookahead symbol. */ | ||
| 1583 | YYSTYPE yylval; | ||
| 1584 | /* Number of syntax errors so far. */ | ||
| 1585 | int yynerrs; | ||
| 1586 | |||
| 1587 | |||
| 1588 | /*----------. | ||
| 1589 | | yyparse. | | ||
| 1590 | `----------*/ | ||
| 1591 | |||
| 1592 | int | ||
| 1593 | yyparse (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 | `-----------*/ | ||
| 1733 | yybackup: | ||
| 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 | `-----------------------------------------------------------*/ | ||
| 1799 | yydefault: | ||
| 1800 | yyn = yydefact[yystate]; | ||
| 1801 | if (yyn == 0) | ||
| 1802 | goto yyerrlab; | ||
| 1803 | goto yyreduce; | ||
| 1804 | |||
| 1805 | |||
| 1806 | /*-----------------------------. | ||
| 1807 | | yyreduce -- Do a reduction. | | ||
| 1808 | `-----------------------------*/ | ||
| 1809 | yyreduce: | ||
| 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 | `--------------------------------------*/ | ||
| 2954 | yyerrlab: | ||
| 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 | `---------------------------------------------------*/ | ||
| 3028 | yyerrorlab: | ||
| 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 | `-------------------------------------------------------------*/ | ||
| 3048 | yyerrlab1: | ||
| 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 | `-------------------------------------*/ | ||
| 3092 | yyacceptlab: | ||
| 3093 | yyresult = 0; | ||
| 3094 | goto yyreturn; | ||
| 3095 | |||
| 3096 | /*-----------------------------------. | ||
| 3097 | | yyabortlab -- YYABORT comes here. | | ||
| 3098 | `-----------------------------------*/ | ||
| 3099 | yyabortlab: | ||
| 3100 | yyresult = 1; | ||
| 3101 | goto yyreturn; | ||
| 3102 | |||
| 3103 | #if !defined yyoverflow || YYERROR_VERBOSE | ||
| 3104 | /*-------------------------------------------------. | ||
| 3105 | | yyexhaustedlab -- memory exhaustion comes here. | | ||
| 3106 | `-------------------------------------------------*/ | ||
| 3107 | yyexhaustedlab: | ||
| 3108 | yyerror (YY_("memory exhausted")); | ||
| 3109 | yyresult = 2; | ||
| 3110 | /* Fall through. */ | ||
| 3111 | #endif | ||
| 3112 | |||
| 3113 | yyreturn: | ||
| 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 | } | ||
| @@ -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 | ||
| 40 | extern 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 | |||
| 162 | union 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 | |||
| 193 | typedef union YYSTYPE YYSTYPE; | ||
| 194 | # define YYSTYPE_IS_TRIVIAL 1 | ||
| 195 | # define YYSTYPE_IS_DECLARED 1 | ||
| 196 | #endif | ||
| 197 | |||
| 198 | |||
| 199 | extern YYSTYPE yylval; | ||
| 200 | |||
| 201 | int yyparse (void); | ||
| 202 | |||
| 203 | #endif /* !YY_YY_CHUCK_TAB_H_INCLUDED */ | ||
| @@ -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 | ||
| 46 | int yylex( void ); | ||
| 47 | |||
| 48 | void yyerror( char *s ) | ||
| 49 | { | ||
| 50 | EM_error( EM_tokPos, "%s", s ); | ||
| 51 | } | ||
| 52 | |||
| 53 | a_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 | |||
| 180 | program | ||
| 181 | : program_section { $$ = g_program = new_program( $1, EM_lineNum ); } | ||
| 182 | | program_section program { $$ = g_program = prepend_program( $1, $2, EM_lineNum ); } | ||
| 183 | ; | ||
| 184 | |||
| 185 | program_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 | |||
| 191 | class_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 | |||
| 202 | class_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 | |||
| 209 | class_body | ||
| 210 | : class_body2 { $$ = $1; } | ||
| 211 | | { $$ = NULL; } | ||
| 212 | ; | ||
| 213 | |||
| 214 | class_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 | |||
| 220 | class_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 | |||
| 226 | iface_ext | ||
| 227 | : EXTENDS id_list { $$ = new_class_ext( NULL, $2, EM_lineNum ); } | ||
| 228 | ; | ||
| 229 | |||
| 230 | id_list | ||
| 231 | : ID { $$ = new_id_list( $1, EM_lineNum ); } | ||
| 232 | | ID COMMA id_list { $$ = prepend_id_list( $1, $3, EM_lineNum ); } | ||
| 233 | ; | ||
| 234 | |||
| 235 | id_dot | ||
| 236 | : ID { $$ = new_id_list( $1, EM_lineNum ); } | ||
| 237 | | ID DOT id_dot { $$ = prepend_id_list( $1, $3, EM_lineNum ); } | ||
| 238 | ; | ||
| 239 | |||
| 240 | function_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 | |||
| 251 | class_decl | ||
| 252 | : PUBLIC { $$ = ae_key_public; } | ||
| 253 | | PRIVATE { $$ = ae_key_private; } | ||
| 254 | | { $$ = ae_key_private; } | ||
| 255 | ; | ||
| 256 | |||
| 257 | function_decl | ||
| 258 | : FUNCTION { $$ = ae_key_func; } | ||
| 259 | | PUBLIC { $$ = ae_key_public; } | ||
| 260 | | PROTECTED { $$ = ae_key_protected; } | ||
| 261 | | PRIVATE { $$ = ae_key_private; } | ||
| 262 | ; | ||
| 263 | |||
| 264 | static_decl | ||
| 265 | : STATIC { $$ = ae_key_static; } | ||
| 266 | | ABSTRACT { $$ = ae_key_abstract; } | ||
| 267 | | { $$ = ae_key_instance; } | ||
| 268 | ; | ||
| 269 | |||
| 270 | type_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 | |||
| 275 | type_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 | |||
| 285 | type_decl | ||
| 286 | : type_decl_a { $$ = $1; } | ||
| 287 | | type_decl_b { $$ = $1; } | ||
| 288 | // | type_decl_c { $$ = $1; } | ||
| 289 | ; | ||
| 290 | |||
| 291 | type_decl2 | ||
| 292 | : type_decl { $$ = $1; } | ||
| 293 | | type_decl array_empty { $$ = add_type_decl_array( $1, $2, EM_lineNum ); } | ||
| 294 | ; | ||
| 295 | |||
| 296 | arg_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 | |||
| 301 | statement_list | ||
| 302 | : statement { $$ = new_stmt_list( $1, EM_lineNum ); } | ||
| 303 | | statement statement_list { $$ = prepend_stmt_list( $1, $2, EM_lineNum ); } | ||
| 304 | ; | ||
| 305 | |||
| 306 | statement | ||
| 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 | |||
| 315 | jump_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 | |||
| 322 | selection_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 | |||
| 329 | loop_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 | |||
| 346 | code_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 | |||
| 351 | expression_statement | ||
| 352 | : SEMICOLON { $$ = NULL; } | ||
| 353 | | expression SEMICOLON { $$ = new_stmt_from_expression( $1, EM_lineNum ); } | ||
| 354 | ; | ||
| 355 | |||
| 356 | expression | ||
| 357 | : chuck_expression { $$ = $1; } | ||
| 358 | | chuck_expression COMMA expression { $$ = prepend_expression( $1, $3, EM_lineNum ); } | ||
| 359 | ; | ||
| 360 | |||
| 361 | chuck_expression | ||
| 362 | : arrow_expression { $$ = $1; } | ||
| 363 | | chuck_expression chuck_operator arrow_expression | ||
| 364 | { $$ = new_exp_from_binary( $1, $2, $3, EM_lineNum ); } | ||
| 365 | ; | ||
| 366 | |||
| 367 | arrow_expression | ||
| 368 | : decl_expression { $$ = $1; } | ||
| 369 | | arrow_expression arrow_operator decl_expression | ||
| 370 | { $$ = new_exp_from_binary( $1, $2, $3, EM_lineNum ); } | ||
| 371 | ; | ||
| 372 | |||
| 373 | array_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 | |||
| 379 | array_empty | ||
| 380 | : LBRACK RBRACK { $$ = new_array_sub( NULL, EM_lineNum ); } | ||
| 381 | | array_empty LBRACK RBRACK { $$ = prepend_array_sub( $1, NULL, EM_lineNum ); } | ||
| 382 | ; | ||
| 383 | |||
| 384 | decl_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 | |||
| 392 | var_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 | |||
| 397 | var_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 | |||
| 403 | complex_exp | ||
| 404 | : POUNDPAREN expression RPAREN | ||
| 405 | { $$ = new_complex( $2, EM_lineNum ); } | ||
| 406 | ; | ||
| 407 | |||
| 408 | polar_exp | ||
| 409 | : PERCENTPAREN expression RPAREN | ||
| 410 | { $$ = new_polar( $2, EM_lineNum ); } | ||
| 411 | ; | ||
| 412 | |||
| 413 | vec_exp // ge: added 1.3.5.3 | ||
| 414 | : ATPAREN expression RPAREN | ||
| 415 | { $$ = new_vec( $2, EM_lineNum ); } | ||
| 416 | ; | ||
| 417 | |||
| 418 | chuck_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 | |||
| 435 | arrow_operator | ||
| 436 | : ARROW_LEFT { $$ = ae_op_arrow_left; } | ||
| 437 | | ARROW_RIGHT { $$ = ae_op_arrow_right; } | ||
| 438 | ; | ||
| 439 | |||
| 440 | conditional_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 | |||
| 446 | logical_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 | |||
| 452 | logical_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 | |||
| 458 | inclusive_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 | |||
| 464 | exclusive_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 | |||
| 470 | and_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 | |||
| 476 | equality_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 | |||
| 484 | relational_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 | |||
| 496 | shift_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 | |||
| 504 | additive_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 | |||
| 512 | multiplicative_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 | |||
| 522 | tilda_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 | |||
| 528 | cast_expression | ||
| 529 | : unary_expression { $$ = $1; } | ||
| 530 | | cast_expression DOLLAR type_decl | ||
| 531 | { $$ = new_exp_from_cast( $3, $1, EM_lineNum ); } | ||
| 532 | ; | ||
| 533 | |||
| 534 | unary_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 | |||
| 554 | unary_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 | |||
| 564 | dur_expression | ||
| 565 | : postfix_expression | ||
| 566 | | dur_expression COLONCOLON postfix_expression | ||
| 567 | { $$ = new_exp_from_dur( $1, $3, EM_lineNum ); } | ||
| 568 | ; | ||
| 569 | |||
| 570 | postfix_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 | ||
| 587 | primary_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 | ; | ||
| @@ -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 | |||
| 38 | a_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 | |||
| 47 | a_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 | |||
| 56 | a_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 | |||
| 66 | a_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 | |||
| 76 | a_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 | |||
| 86 | a_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 | |||
| 96 | a_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 | |||
| 105 | a_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 | |||
| 115 | a_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 | |||
| 127 | a_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 | |||
| 141 | a_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 | |||
| 155 | a_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 | |||
| 169 | a_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 | |||
| 183 | a_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 | |||
| 197 | a_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 | |||
| 212 | a_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 | |||
| 225 | a_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 | |||
| 237 | a_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 | |||
| 248 | a_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 | |||
| 259 | a_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 | |||
| 271 | a_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 | |||
| 283 | a_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 | |||
| 295 | a_Exp prepend_expression( a_Exp exp, a_Exp list, int pos ) | ||
| 296 | { | ||
| 297 | exp->next = list; | ||
| 298 | return exp; | ||
| 299 | } | ||
| 300 | |||
| 301 | a_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 | |||
| 316 | a_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 | |||
| 330 | a_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 | |||
| 346 | a_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 | |||
| 360 | a_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 | |||
| 374 | a_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 | |||
| 388 | a_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 | |||
| 402 | a_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 | |||
| 416 | a_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 | |||
| 430 | a_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 | |||
| 444 | a_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 | |||
| 458 | a_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 | |||
| 472 | a_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 | |||
| 486 | a_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 | |||
| 500 | a_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 | |||
| 514 | a_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 | |||
| 528 | a_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 | |||
| 544 | a_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 | |||
| 552 | a_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 | |||
| 567 | a_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 | |||
| 581 | a_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 | |||
| 596 | a_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 | |||
| 611 | a_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 | |||
| 626 | a_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 | |||
| 639 | a_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 | |||
| 649 | a_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 | |||
| 659 | a_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 | |||
| 667 | a_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 | |||
| 678 | a_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 | |||
| 686 | a_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 | |||
| 698 | a_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 | |||
| 708 | a_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 | |||
| 726 | a_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 | |||
| 739 | a_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 | |||
| 748 | a_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 | |||
| 757 | a_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 | |||
| 766 | a_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 | |||
| 776 | a_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 | |||
| 786 | a_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 | |||
| 795 | void clean_exp( a_Exp exp ) | ||
| 796 | { | ||
| 797 | if( !exp ) return; | ||
| 798 | clean_exp( exp->next ); | ||
| 799 | free( exp ); | ||
| 800 | } | ||
| 801 | |||
| 802 | a_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 | |||
| 834 | a_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 | |||
| 866 | error: | ||
| 867 | clean_exp( exp ); | ||
| 868 | return a; | ||
| 869 | } | ||
| 870 | |||
| 871 | a_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 | |||
| 881 | a_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 | |||
| 891 | a_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 | |||
| 905 | void 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 | |||
| 921 | static 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 | |||
| 965 | const 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 | } | ||
| @@ -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) | ||
| 38 | extern "C" { | ||
| 39 | #endif | ||
| 40 | |||
| 41 | // pos | ||
| 42 | typedef int a_Pos; | ||
| 43 | |||
| 44 | // enum oper | ||
| 45 | typedef 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 | |||
| 59 | const char * op2str( ae_Operator op ); | ||
| 60 | |||
| 61 | // enum key words | ||
| 62 | typedef 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 | //----------------------------------------------------------------------------- | ||
| 73 | typedef struct a_Program_ * a_Program; | ||
| 74 | typedef struct a_Section_ * a_Section; | ||
| 75 | typedef struct a_Stmt_List_ * a_Stmt_List; | ||
| 76 | typedef struct a_Class_Def_ * a_Class_Def; | ||
| 77 | typedef struct a_Func_Def_ * a_Func_Def; | ||
| 78 | typedef struct a_Code_Segment_ * a_Code_Segment; | ||
| 79 | typedef struct a_Stmt_ * a_Stmt; | ||
| 80 | typedef struct a_Exp_ * a_Exp; | ||
| 81 | typedef struct a_Exp_Chuck_ * a_Exp_Chuck; | ||
| 82 | typedef struct a_Exp_Binary_ * a_Exp_Binary; | ||
| 83 | typedef struct a_Exp_Cast_ * a_Exp_Cast; | ||
| 84 | typedef struct a_Exp_Unary_ * a_Exp_Unary; | ||
| 85 | typedef struct a_Exp_Postfix_ * a_Exp_Postfix; | ||
| 86 | typedef struct a_Exp_Primary_ * a_Exp_Primary; | ||
| 87 | typedef struct a_Exp_Dur_ * a_Exp_Dur; | ||
| 88 | typedef struct a_Exp_Array_ * a_Exp_Array; | ||
| 89 | typedef struct a_Exp_Func_Call_ * a_Exp_Func_Call; | ||
| 90 | typedef struct a_Exp_Dot_Member_ * a_Exp_Dot_Member; | ||
| 91 | typedef struct a_Exp_If_ * a_Exp_If; | ||
| 92 | typedef struct a_Exp_Decl_ * a_Exp_Decl; | ||
| 93 | typedef struct a_Exp_Hack_ * a_Exp_Hack; | ||
| 94 | typedef struct a_Stmt_Code_ * a_Stmt_Code; | ||
| 95 | typedef struct a_Stmt_If_ * a_Stmt_If; | ||
| 96 | typedef struct a_Stmt_While_ * a_Stmt_While; | ||
| 97 | typedef struct a_Stmt_Until_ * a_Stmt_Until; | ||
| 98 | typedef struct a_Stmt_For_ * a_Stmt_For; | ||
| 99 | typedef struct a_Stmt_Loop_ * a_Stmt_Loop; | ||
| 100 | typedef struct a_Stmt_Switch_ * a_Stmt_Switch; | ||
| 101 | typedef struct a_Stmt_Break_ * a_Stmt_Break; | ||
| 102 | typedef struct a_Stmt_Continue_ * a_Stmt_Continue; | ||
| 103 | typedef struct a_Stmt_Return_ * a_Stmt_Return; | ||
| 104 | typedef struct a_Stmt_Case_ * a_Stmt_Case; | ||
| 105 | typedef struct a_Stmt_GotoLabel_ * a_Stmt_GotoLabel; | ||
| 106 | typedef struct a_Decl_ * a_Decl; | ||
| 107 | typedef struct a_Var_Decl_ * a_Var_Decl; | ||
| 108 | typedef struct a_Var_Decl_List_ * a_Var_Decl_List; | ||
| 109 | typedef struct a_Type_Decl_ * a_Type_Decl; | ||
| 110 | typedef struct a_Arg_List_ * a_Arg_List; | ||
| 111 | typedef struct a_Id_List_ * a_Id_List; | ||
| 112 | typedef struct a_Class_Ext_ * a_Class_Ext; | ||
| 113 | typedef struct a_Class_Body_ * a_Class_Body; | ||
| 114 | typedef struct a_Array_Sub_ * a_Array_Sub; | ||
| 115 | typedef struct a_Complex_ * a_Complex; | ||
| 116 | typedef struct a_Polar_ * a_Polar; | ||
| 117 | typedef struct a_Vec_ * a_Vec; // ge: added 1.3.5.3 | ||
| 118 | |||
| 119 | // forward reference for type | ||
| 120 | typedef struct Chuck_Type * t_CKTYPE; | ||
| 121 | typedef struct Chuck_Value * t_CKVALUE; | ||
| 122 | typedef struct Chuck_Func * t_CKFUNC; | ||
| 123 | typedef struct Chuck_Namespace * t_CKNSPC; | ||
| 124 | typedef struct Chuck_VM_Code * t_CKVMCODE; | ||
| 125 | |||
| 126 | |||
| 127 | |||
| 128 | |||
| 129 | //------------------------------------------------------------------------------ | ||
| 130 | // functions | ||
| 131 | //------------------------------------------------------------------------------ | ||
| 132 | a_Program new_program( a_Section section, int pos ); | ||
| 133 | a_Program prepend_program( a_Section section, a_Program program, int pos ); | ||
| 134 | a_Section new_section_stmt( a_Stmt_List stmt_list, int pos ); | ||
| 135 | a_Section new_section_func_def( a_Func_Def func_def, int pos ); | ||
| 136 | a_Section new_section_class_def( a_Class_Def class_def, int pos ); | ||
| 137 | a_Stmt_List new_stmt_list( a_Stmt stmt, int pos ); | ||
| 138 | a_Stmt_List prepend_stmt_list( a_Stmt stmt, a_Stmt_List stmt_list, int pos ); | ||
| 139 | a_Stmt new_stmt_from_expression( a_Exp exp, int pos ); | ||
| 140 | a_Stmt new_stmt_from_code( a_Stmt_List code, int pos ); | ||
| 141 | a_Stmt new_stmt_from_while( a_Exp cond, a_Stmt body, int pos ); | ||
| 142 | a_Stmt new_stmt_from_do_while( a_Exp cond, a_Stmt body, int pos ); | ||
| 143 | a_Stmt new_stmt_from_until( a_Exp cond, a_Stmt body, int pos ); | ||
| 144 | a_Stmt new_stmt_from_do_until( a_Exp cond, a_Stmt body, int pos ); | ||
| 145 | a_Stmt new_stmt_from_for( a_Stmt c1, a_Stmt c2, a_Exp c3, a_Stmt body, int pos ); | ||
| 146 | a_Stmt new_stmt_from_loop( a_Exp cond, a_Stmt body, int pos ); | ||
| 147 | a_Stmt new_stmt_from_if( a_Exp cond, a_Stmt if_body, a_Stmt else_body, int pos ); | ||
| 148 | a_Stmt new_stmt_from_switch( a_Exp exp, int pos ); | ||
| 149 | a_Stmt new_stmt_from_break( int pos ); | ||
| 150 | a_Stmt new_stmt_from_continue( int pos ); | ||
| 151 | a_Stmt new_stmt_from_return( a_Exp exp, int pos ); | ||
| 152 | a_Stmt new_stmt_from_label( c_str xid, int pos ); | ||
| 153 | a_Stmt new_stmt_from_case( a_Exp exp, int pos ); | ||
| 154 | a_Exp prepend_expression( a_Exp exp, a_Exp list, int pos ); | ||
| 155 | a_Exp new_exp_from_binary( a_Exp lhs, ae_Operator oper, a_Exp rhs, int pos ); | ||
| 156 | a_Exp new_exp_from_unary( ae_Operator oper, a_Exp exp, int pos ); | ||
| 157 | a_Exp new_exp_from_unary2( ae_Operator oper, a_Type_Decl type, a_Array_Sub array, int pos ); | ||
| 158 | a_Exp new_exp_from_unary3( ae_Operator oper, a_Stmt code, int pos ); | ||
| 159 | a_Exp new_exp_from_cast( a_Type_Decl type, a_Exp exp, int pos ); | ||
| 160 | a_Exp new_exp_from_array( a_Exp base, a_Array_Sub indices, int pos ); | ||
| 161 | a_Exp new_exp_from_array_lit( a_Array_Sub exp_list, int pos ); | ||
| 162 | a_Exp new_exp_from_func_call( a_Exp base, a_Exp args, int pos ); | ||
| 163 | a_Exp new_exp_from_member_dot( a_Exp base, c_str member, int pos ); | ||
| 164 | a_Exp new_exp_from_postfix( a_Exp base, ae_Operator op, int pos ); | ||
| 165 | a_Exp new_exp_from_dur( a_Exp base, a_Exp unit, int pos ); | ||
| 166 | a_Exp new_exp_from_id( c_str xid, int pos ); | ||
| 167 | a_Exp new_exp_from_int( long num, int pos ); | ||
| 168 | a_Exp new_exp_from_uint( unsigned long num, int pos ); | ||
| 169 | a_Exp new_exp_from_float( double num, int pos ); | ||
| 170 | a_Exp new_exp_from_str( c_str str, int pos ); | ||
| 171 | a_Exp new_exp_from_char( c_str chr, int pos ); | ||
| 172 | a_Exp new_exp_from_if( a_Exp cond, a_Exp lhs, a_Exp rhs, int pos ); | ||
| 173 | a_Exp new_exp_from_complex( a_Complex, int pos ); | ||
| 174 | a_Exp new_exp_from_polar( a_Polar, int pos ); | ||
| 175 | a_Exp new_exp_from_vec( a_Vec, int pos ); // ge: added 1.3.5.3 | ||
| 176 | a_Exp new_exp_decl_external( a_Type_Decl type_decl, a_Var_Decl_List var_decl_list, int is_static, int pos ); | ||
| 177 | a_Exp new_exp_decl( a_Type_Decl type_decl, a_Var_Decl_List var_decl_list, int is_static, int pos ); | ||
| 178 | a_Exp new_exp_from_hack( a_Exp exp, int pos ); | ||
| 179 | a_Exp new_exp_from_nil( int pos ); | ||
| 180 | a_Var_Decl_List new_var_decl_list( a_Var_Decl var_decl, int pos ); | ||
| 181 | a_Var_Decl_List prepend_var_decl_list( a_Var_Decl var_decl, a_Var_Decl_List list, int pos ); | ||
| 182 | a_Var_Decl new_var_decl( c_constr xid, a_Array_Sub array, int pos ); | ||
| 183 | a_Type_Decl new_type_decl( a_Id_List xid, int ref, int pos ); | ||
| 184 | a_Type_Decl add_type_decl_array( a_Type_Decl type_decl, a_Array_Sub array, int pos ); | ||
| 185 | a_Arg_List new_arg_list( a_Type_Decl type_decl, a_Var_Decl var_decl, int pos ); | ||
| 186 | a_Arg_List prepend_arg_list( a_Type_Decl type_decl, a_Var_Decl var_decl, a_Arg_List arg_list, int pos ); | ||
| 187 | a_Array_Sub new_array_sub( a_Exp exp, int pos ); | ||
| 188 | a_Array_Sub prepend_array_sub( a_Array_Sub array, a_Exp exp, int pos ); | ||
| 189 | a_Complex new_complex( a_Exp re, int pos ); | ||
| 190 | a_Polar new_polar( a_Exp mod, int pos ); // ge: added 1.3.5.3 | ||
| 191 | a_Vec new_vec( a_Exp e, int pos ); | ||
| 192 | |||
| 193 | a_Class_Def new_class_def( ae_Keyword class_decl, a_Id_List xid, a_Class_Ext ext, a_Class_Body body, int pos ); | ||
| 194 | a_Class_Body new_class_body( a_Section section, int pos ); | ||
| 195 | a_Class_Body prepend_class_body( a_Section section, a_Class_Body body, int pos ); | ||
| 196 | a_Class_Ext new_class_ext( a_Id_List extend_id, a_Id_List impl_list, int pos ); | ||
| 197 | a_Class_Def new_iface_def( ae_Keyword class_decl, a_Id_List xid, a_Class_Ext ext, a_Class_Body body, int pos ); | ||
| 198 | a_Id_List new_id_list( c_constr xid, int pos ); | ||
| 199 | a_Id_List prepend_id_list( c_constr xid, a_Id_List list, int pos ); | ||
| 200 | void clean_exp( a_Exp exp ); | ||
| 201 | a_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 | |||
| 205 | void delete_id_list( a_Id_List x ); | ||
| 206 | |||
| 207 | |||
| 208 | |||
| 209 | |||
| 210 | //------------------------------------------------------------------------------ | ||
| 211 | // structs | ||
| 212 | //------------------------------------------------------------------------------ | ||
| 213 | struct a_Exp_Binary_ { a_Exp lhs; ae_Operator op; a_Exp rhs; t_CKFUNC ck_func; int linepos; a_Exp self; }; | ||
| 214 | struct a_Exp_Cast_ { a_Type_Decl type; a_Exp exp; int linepos; a_Exp self; }; | ||
| 215 | struct 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; }; | ||
| 217 | struct a_Exp_Postfix_ { a_Exp exp; ae_Operator op; int linepos; a_Exp self; }; | ||
| 218 | struct a_Exp_Dur_ { a_Exp base; a_Exp unit; int linepos; a_Exp self; }; | ||
| 219 | struct a_Exp_Array_ { a_Exp base; a_Array_Sub indices; int linepos; a_Exp self; }; | ||
| 220 | struct 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; }; | ||
| 222 | struct a_Exp_Dot_Member_ { a_Exp base; t_CKTYPE t_base; S_Symbol xid; int linepos; a_Exp self; }; | ||
| 223 | struct a_Exp_If_ { a_Exp cond; a_Exp if_exp; a_Exp else_exp; int linepos; a_Exp self; }; | ||
| 224 | struct 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; }; | ||
| 226 | struct a_Exp_Hack_ { a_Exp exp; int linepos; a_Exp self; }; | ||
| 227 | struct a_Var_Decl_List_ { a_Var_Decl var_decl; a_Var_Decl_List next; int linepos; a_Exp self; }; | ||
| 228 | struct 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; }; | ||
| 230 | struct a_Type_Decl_ { a_Id_List xid; a_Array_Sub array; int ref; int linepos; /*a_Exp self;*/ }; | ||
| 231 | struct a_Array_Sub_ { t_CKUINT depth; a_Exp exp_list; int linepos; a_Exp self; | ||
| 232 | int err_num; int err_pos; }; | ||
| 233 | struct 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; }; | ||
| 235 | struct a_Complex_ { a_Exp re; a_Exp im; int linepos; a_Exp self; }; | ||
| 236 | struct a_Polar_ { a_Exp mod; a_Exp phase; int linepos; a_Exp self; }; | ||
| 237 | struct a_Vec_ { a_Exp args; int numdims; int linepos; a_Exp self; }; // ge: added 1.3.5.3 | ||
| 238 | |||
| 239 | // enum primary exp type | ||
| 240 | typedef 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 | |||
| 246 | struct 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 | ||
| 270 | typedef 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 | ||
| 275 | typedef enum { ae_meta_value = 0, ae_meta_var } ae_Exp_Meta; | ||
| 276 | |||
| 277 | struct 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 | |||
| 307 | struct a_Stmt_While_ { int is_do; a_Exp cond; a_Stmt body; int linepos; a_Stmt self; }; | ||
| 308 | struct a_Stmt_Until_ { int is_do; a_Exp cond; a_Stmt body; int linepos; a_Stmt self; }; | ||
| 309 | struct a_Stmt_For_ { a_Stmt c1; a_Stmt c2; a_Exp c3; a_Stmt body; int linepos; a_Stmt self; }; | ||
| 310 | struct a_Stmt_Loop_ { a_Exp cond; a_Stmt body; int linepos; a_Stmt self; }; | ||
| 311 | struct a_Stmt_Code_ { a_Stmt_List stmt_list; int linepos; a_Stmt self; }; | ||
| 312 | struct a_Stmt_If_ { a_Exp cond; a_Stmt if_body; a_Stmt else_body; int linepos; a_Stmt self; }; | ||
| 313 | struct a_Stmt_Switch_ { a_Exp val; int linepos; a_Stmt self; }; | ||
| 314 | struct a_Stmt_Break_ { int linepos; a_Stmt self; }; | ||
| 315 | struct a_Stmt_Continue_ { int linepos; a_Stmt self; }; | ||
| 316 | struct a_Stmt_Return_ { a_Exp val; int linepos; a_Stmt self; }; | ||
| 317 | struct a_Stmt_Case_ { a_Exp exp; int linepos; a_Stmt self; }; | ||
| 318 | struct a_Stmt_GotoLabel_ { S_Symbol name; int linepos; a_Stmt self; }; | ||
| 319 | |||
| 320 | // enum values for stmt type | ||
| 321 | typedef 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 | |||
| 326 | struct 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 | |||
| 351 | struct a_Stmt_List_ { a_Stmt stmt; a_Stmt_List next; int linepos; }; | ||
| 352 | struct 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; }; | ||
| 355 | struct a_Class_Ext_ { a_Id_List extend_id; a_Id_List impl_list; int linepos; }; | ||
| 356 | struct a_Class_Body_ { a_Section section; a_Class_Body next; int linepos; }; | ||
| 357 | struct a_Id_List_ { S_Symbol xid; a_Id_List next; int linepos; }; | ||
| 358 | |||
| 359 | typedef 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; }; | ||
| 363 | struct 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 | ||
| 380 | typedef enum { ae_section_stmt, ae_section_func, ae_section_class | ||
| 381 | } ae_Section_Type; | ||
| 382 | |||
| 383 | struct 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 | |||
| 397 | struct 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 | ||
| @@ -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++) | ||
| 47 | class Chuck_Compiler; | ||
| 48 | class Chuck_VM; | ||
| 49 | class Chuck_Env; | ||
| 50 | class Chuck_IO_Chout; | ||
| 51 | class Chuck_IO_Cherr; | ||
| 52 | |||
| 53 | // forward references ("C") | ||
| 54 | struct ck_socket_; | ||
| 55 | typedef 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 | //----------------------------------------------------------------------------- | ||
| 65 | struct 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 | ||
| @@ -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 | |||
| 57 | using namespace std; | ||
| 58 | |||
| 59 | |||
| 60 | |||
| 61 | |||
| 62 | // function prototypes | ||
| 63 | t_CKBOOL load_internal_modules( Chuck_Compiler * compiler ); | ||
| 64 | t_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); | ||
| 68 | t_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 | //----------------------------------------------------------------------------- | ||
| 77 | Chuck_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 | //----------------------------------------------------------------------------- | ||
| 93 | Chuck_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 | //----------------------------------------------------------------------------- | ||
| 106 | t_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 | |||
| 139 | error: | ||
| 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 | //----------------------------------------------------------------------------- | ||
| 156 | void 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 | //----------------------------------------------------------------------------- | ||
| 192 | t_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 | |||
| 225 | error: | ||
| 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 | //----------------------------------------------------------------------------- | ||
| 246 | void 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 | //----------------------------------------------------------------------------- | ||
| 261 | t_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 | |||
| 304 | cleanup: | ||
| 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 | //----------------------------------------------------------------------------- | ||
| 329 | t_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 | //----------------------------------------------------------------------------- | ||
| 351 | t_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 | //----------------------------------------------------------------------------- | ||
| 386 | t_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 | //----------------------------------------------------------------------------- | ||
| 421 | t_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 | //----------------------------------------------------------------------------- | ||
| 454 | t_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 | |||
| 497 | cleanup: | ||
| 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 | //----------------------------------------------------------------------------- | ||
| 521 | Chuck_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 | //----------------------------------------------------------------------------- | ||
| 533 | Chuck_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 | //----------------------------------------------------------------------------- | ||
| 545 | t_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 | //----------------------------------------------------------------------------- | ||
| 558 | Chuck_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 | //----------------------------------------------------------------------------- | ||
| 570 | t_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 | //----------------------------------------------------------------------------- | ||
| 601 | t_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 | |||
| 668 | error: | ||
| 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 | //----------------------------------------------------------------------------- | ||
| 688 | t_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 | //----------------------------------------------------------------------------- | ||
| 723 | static 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 | //----------------------------------------------------------------------------- | ||
| 739 | t_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 | //----------------------------------------------------------------------------- | ||
| 835 | t_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 | /* | ||
| 886 | error: | ||
| 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 | |||
| @@ -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 | ||
| 45 | struct Chuck_DLL; | ||
| 46 | |||
| 47 | |||
| 48 | |||
| 49 | |||
| 50 | //----------------------------------------------------------------------------- | ||
| 51 | // name: struct Chuck_Compiler | ||
| 52 | // desc: the sum of the components in compilation | ||
| 53 | //----------------------------------------------------------------------------- | ||
| 54 | struct Chuck_Compiler | ||
| 55 | { | ||
| 56 | protected: // data | ||
| 57 | // carrier | ||
| 58 | Chuck_Carrier * m_carrier; | ||
| 59 | |||
| 60 | public: // 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 | |||
| 71 | public: // 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 | |||
| 85 | public: // 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 | |||
| 97 | public: // 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 | |||
| 102 | public: // 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 | |||
| 113 | protected: // 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 | ||
| 133 | extern "C" void all_detach(); | ||
| 134 | |||
| 135 | |||
| 136 | |||
| 137 | |||
| 138 | #endif | ||
| @@ -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 | ||
| 59 | typedef struct { t_CKFLOAT re ; t_CKFLOAT im ; } t_CKCOMPLEX; | ||
| 60 | // polar type | ||
| 61 | typedef struct { t_CKFLOAT modulus ; t_CKFLOAT phase ; } t_CKPOLAR; | ||
| 62 | |||
| 63 | // vector types | ||
| 64 | typedef struct { t_CKFLOAT x ; t_CKFLOAT y ; t_CKFLOAT z ; } t_CKVEC3; | ||
| 65 | typedef struct { t_CKFLOAT x ; t_CKFLOAT y ; t_CKFLOAT z ; t_CKFLOAT w ; } t_CKVEC4; | ||
| 66 | typedef 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 | |||
| 96 | typedef char * c_str; | ||
| 97 | typedef 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 | ||
| 117 | typedef 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 | ||
| @@ -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> | ||
| 44 | using namespace std; | ||
| 45 | |||
| 46 | |||
| 47 | |||
| 48 | |||
| 49 | #if defined(__MACOSX_CORE__) | ||
| 50 | char g_default_chugin_path[] = "/usr/local/lib/chuck:/Library/Application Support/ChucK/ChuGins:~/Library/Application Support/ChucK/ChuGins"; | ||
| 51 | #elif defined(__PLATFORM_WIN32__) | ||
| 52 | char g_default_chugin_path[] = "C:\\WINDOWS\\system32\\ChucK;C:\\Program Files\\ChucK\\chugins;C:\\Program Files (x86)\\ChucK\\chugins"; | ||
| 53 | #else // Linux/Cygwin | ||
| 54 | char g_default_chugin_path[] = "/usr/local/lib/chuck"; | ||
| 55 | #endif | ||
| 56 | |||
| 57 | char g_chugin_path_envvar[] = "CHUCK_CHUGIN_PATH"; | ||
| 58 | |||
| 59 | |||
| 60 | |||
| 61 | |||
| 62 | //----------------------------------------------------------------------------- | ||
| 63 | // internal implementation of query functions | ||
| 64 | //----------------------------------------------------------------------------- | ||
| 65 | |||
| 66 | |||
| 67 | |||
| 68 | t_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 | //----------------------------------------------------------------------------- | ||
| 76 | void 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 | //----------------------------------------------------------------------------- | ||
| 89 | void 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 | //----------------------------------------------------------------------------- | ||
| 149 | void 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 | //----------------------------------------------------------------------------- | ||
| 177 | void 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 | //----------------------------------------------------------------------------- | ||
| 214 | void 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 | //----------------------------------------------------------------------------- | ||
| 243 | void 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 | //----------------------------------------------------------------------------- | ||
| 272 | t_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 | //----------------------------------------------------------------------------- | ||
| 329 | void 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 | //----------------------------------------------------------------------------- | ||
| 361 | void 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 | //----------------------------------------------------------------------------- | ||
| 395 | void 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 | //----------------------------------------------------------------------------- | ||
| 436 | void 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 | //----------------------------------------------------------------------------- | ||
| 477 | void 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 | //----------------------------------------------------------------------------- | ||
| 493 | void 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 | //----------------------------------------------------------------------------- | ||
| 522 | t_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 | //----------------------------------------------------------------------------- | ||
| 565 | t_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 | //----------------------------------------------------------------------------- | ||
| 581 | t_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 | ||
| 594 | t_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 | ||
| 607 | t_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 | //------------------------------------------------------------------------------ | ||
| 624 | Chuck_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 ); } | ||
| 626 | Chuck_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 ); } | ||
| 628 | Chuck_DL_Value * make_new_arg( const char * t, const char * n ) | ||
| 629 | { return new Chuck_DL_Value( t, n ); } | ||
| 630 | Chuck_DL_Value * make_new_mvar( const char * t, const char * n, t_CKBOOL c ) | ||
| 631 | { return new Chuck_DL_Value( t, n, c ); } | ||
| 632 | Chuck_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 | //----------------------------------------------------------------------------- | ||
| 642 | t_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 | //----------------------------------------------------------------------------- | ||
| 673 | t_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 | //----------------------------------------------------------------------------- | ||
| 694 | t_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 | //----------------------------------------------------------------------------- | ||
| 706 | const 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 | //----------------------------------------------------------------------------- | ||
| 851 | t_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 | //----------------------------------------------------------------------------- | ||
| 879 | void * 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 | //----------------------------------------------------------------------------- | ||
| 897 | const 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 | //----------------------------------------------------------------------------- | ||
| 909 | const 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 | //----------------------------------------------------------------------------- | ||
| 921 | Chuck_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 | //----------------------------------------------------------------------------- | ||
| 962 | void 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 | //----------------------------------------------------------------------------- | ||
| 981 | Chuck_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 | //----------------------------------------------------------------------------- | ||
| 1004 | Chuck_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 | |||
| 1019 | namespace Chuck_DL_Api | ||
| 1020 | { | ||
| 1021 | Api Api::g_api; | ||
| 1022 | } | ||
| 1023 | |||
| 1024 | |||
| 1025 | static t_CKUINT ck_get_srate(CK_DL_API api, Chuck_VM_Shred * shred) | ||
| 1026 | { | ||
| 1027 | return shred->vm_ref->srate(); | ||
| 1028 | } | ||
| 1029 | |||
| 1030 | static 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 | |||
| 1042 | static 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 | |||
| 1052 | static 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 | |||
| 1061 | static t_CKBOOL ck_get_mvar_int( CK_DL_API api, Chuck_DL_Api::Object, std::string &, t_CKINT & ) | ||
| 1062 | { | ||
| 1063 | return TRUE; | ||
| 1064 | } | ||
| 1065 | |||
| 1066 | static t_CKBOOL ck_get_mvar_float( CK_DL_API api, Chuck_DL_Api::Object, std::string &, t_CKFLOAT & ) | ||
| 1067 | { | ||
| 1068 | return TRUE; | ||
| 1069 | } | ||
| 1070 | |||
| 1071 | static t_CKBOOL ck_get_mvar_dur( CK_DL_API api, Chuck_DL_Api::Object, std::string &, t_CKDUR & ) | ||
| 1072 | { | ||
| 1073 | return TRUE; | ||
| 1074 | } | ||
| 1075 | |||
| 1076 | static t_CKBOOL ck_get_mvar_time( CK_DL_API api, Chuck_DL_Api::Object, std::string &, t_CKTIME & ) | ||
| 1077 | { | ||
| 1078 | return TRUE; | ||
| 1079 | } | ||
| 1080 | |||
| 1081 | static 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 | |||
| 1086 | static 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 | |||
| 1091 | static 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 | |||
| 1102 | Chuck_DL_Api::Api::VMApi::VMApi() : | ||
| 1103 | get_srate(ck_get_srate) | ||
| 1104 | { } | ||
| 1105 | |||
| 1106 | |||
| 1107 | Chuck_DL_Api::Api::ObjectApi::ObjectApi() : | ||
| 1108 | get_type(ck_get_type), | ||
| 1109 | create(ck_create), | ||
| 1110 | create_string(ck_create_string), | ||
| 1111 | get_mvar_int(ck_get_mvar_int), | ||
| 1112 | get_mvar_float(ck_get_mvar_float), | ||
| 1113 | get_mvar_dur(ck_get_mvar_dur), | ||
| 1114 | get_mvar_time(ck_get_mvar_time), | ||
| 1115 | get_mvar_string(ck_get_mvar_string), | ||
| 1116 | get_mvar_object(ck_get_mvar_object), | ||
| 1117 | set_string(ck_set_string) | ||
| 1118 | { } | ||
| 1119 | |||
| 1120 | |||
| 1121 | // windows | ||
| 1122 | #if defined(__WINDOWS_DS__) | ||
| 1123 | extern "C" | ||
| 1124 | { | ||
| 1125 | #include <windows.h> | ||
| 1126 | |||
| 1127 | void *dlopen( const char *path, int mode ) | ||
| 1128 | { | ||
| 1129 | return (void *)LoadLibrary(path); | ||
| 1130 | } | ||
| 1131 | |||
| 1132 | int dlclose( void *handle ) | ||
| 1133 | { | ||
| 1134 | FreeLibrary((HMODULE)handle); | ||
| 1135 | return 1; | ||
| 1136 | } | ||
| 1137 | |||
| 1138 | void *dlsym( void * handle, const char *symbol ) | ||
| 1139 | { | ||
| 1140 | return (void *)GetProcAddress((HMODULE)handle, symbol); | ||
| 1141 | } | ||
| 1142 | |||
| 1143 | const 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 | ||
| @@ -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 | |||
| 60 | extern char g_default_chugin_path[]; | ||
| 61 | extern char g_chugin_path_envvar[]; | ||
| 62 | |||
| 63 | |||
| 64 | |||
| 65 | // forward references | ||
| 66 | struct Chuck_DL_Query; | ||
| 67 | struct Chuck_DL_Class; | ||
| 68 | struct Chuck_DL_Func; | ||
| 69 | struct Chuck_DL_Value; | ||
| 70 | struct Chuck_DL_Ctrl; | ||
| 71 | union Chuck_DL_Return; | ||
| 72 | struct Chuck_DLL; | ||
| 73 | struct Chuck_UGen; | ||
| 74 | struct Chuck_UAna; | ||
| 75 | struct Chuck_UAnaBlobProxy; | ||
| 76 | namespace 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 | |||
| 167 | typedef 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 | //----------------------------------------------------------------------------- | ||
| 239 | extern "C" { | ||
| 240 | // query | ||
| 241 | typedef t_CKUINT (CK_DLL_CALL * f_ck_declversion)(); | ||
| 242 | typedef t_CKBOOL (CK_DLL_CALL * f_ck_query)( Chuck_DL_Query * QUERY ); | ||
| 243 | // object | ||
| 244 | typedef Chuck_Object * (CK_DLL_CALL * f_alloc)( Chuck_VM_Shred * SHRED, CK_DL_API API ); | ||
| 245 | typedef t_CKVOID (CK_DLL_CALL * f_ctor)( Chuck_Object * SELF, void * ARGS, Chuck_VM_Shred * SHRED, CK_DL_API API ); | ||
| 246 | typedef t_CKVOID (CK_DLL_CALL * f_dtor)( Chuck_Object * SELF, Chuck_VM_Shred * SHRED, CK_DL_API API ); | ||
| 247 | typedef t_CKVOID (CK_DLL_CALL * f_mfun)( Chuck_Object * SELF, void * ARGS, Chuck_DL_Return * RETURN, Chuck_VM_Shred * SHRED, CK_DL_API API ); | ||
| 248 | typedef t_CKVOID (CK_DLL_CALL * f_sfun)( void * ARGS, Chuck_DL_Return * RETURN, Chuck_VM_Shred * SHRED, CK_DL_API API ); | ||
| 249 | // ugen specific | ||
| 250 | typedef t_CKBOOL (CK_DLL_CALL * f_tick)( Chuck_Object * SELF, SAMPLE in, SAMPLE * out, Chuck_VM_Shred * SHRED, CK_DL_API API ); | ||
| 251 | typedef 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 ); | ||
| 252 | typedef t_CKVOID (CK_DLL_CALL * f_ctrl)( Chuck_Object * SELF, void * ARGS, Chuck_DL_Return * RETURN, Chuck_VM_Shred * SHRED, CK_DL_API API ); | ||
| 253 | typedef t_CKVOID (CK_DLL_CALL * f_cget)( Chuck_Object * SELF, void * ARGS, Chuck_DL_Return * RETURN, Chuck_VM_Shred * SHRED, CK_DL_API API ); | ||
| 254 | typedef 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 | ||
| 256 | typedef 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 | ||
| 258 | typedef t_CKBOOL (CK_DLL_CALL * f_mainthreadhook)( void * bindle ); | ||
| 259 | // "main thread" quit (stop running hook) | ||
| 260 | typedef 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 | //----------------------------------------------------------------------------- | ||
| 275 | extern "C" { | ||
| 276 | // set name of ckx | ||
| 277 | typedef void ( CK_DLL_CALL * f_setname)( Chuck_DL_Query * query, const char * name ); | ||
| 278 | |||
| 279 | // begin class/namespace, can be nested | ||
| 280 | typedef 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 | ||
| 282 | typedef void (CK_DLL_CALL * f_add_ctor)( Chuck_DL_Query * query, f_ctor ctor ); | ||
| 283 | // add destructor - cannot have args | ||
| 284 | typedef void (CK_DLL_CALL * f_add_dtor)( Chuck_DL_Query * query, f_dtor dtor ); | ||
| 285 | // add member function - args to follow | ||
| 286 | typedef 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 | ||
| 288 | typedef void (CK_DLL_CALL * f_add_sfun)( Chuck_DL_Query * query, f_sfun sfun, const char * type, const char * name ); | ||
| 289 | // add member variable | ||
| 290 | typedef 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 | ||
| 293 | typedef 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 | ||
| 297 | typedef 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 | ||
| 299 | typedef 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 ); | ||
| 300 | typedef 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 ); | ||
| 301 | typedef 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 | ||
| 303 | typedef 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 | ||
| 306 | typedef t_CKBOOL (CK_DLL_CALL * f_end_class)( Chuck_DL_Query * query ); | ||
| 307 | |||
| 308 | // documentation | ||
| 309 | // set current class documentation | ||
| 310 | typedef t_CKBOOL (CK_DLL_CALL * f_doc_class)( Chuck_DL_Query * query, const char * doc ); | ||
| 311 | // add example of current class | ||
| 312 | typedef t_CKBOOL (CK_DLL_CALL * f_add_example)( Chuck_DL_Query * query, const char * ex ); | ||
| 313 | // set current function documentation | ||
| 314 | typedef t_CKBOOL (CK_DLL_CALL * f_doc_func)( Chuck_DL_Query * query, const char * doc ); | ||
| 315 | // set last mvar documentation | ||
| 316 | typedef 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 | //----------------------------------------------------------------------------- | ||
| 324 | struct Chuck_DL_Query | ||
| 325 | { | ||
| 326 | protected: | ||
| 327 | // REFACTOR-2017: carrier ref | ||
| 328 | Chuck_Carrier * m_carrier; | ||
| 329 | |||
| 330 | public: | ||
| 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 | |||
| 336 | public: | ||
| 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 | //----------------------------------------------------------------------------- | ||
| 419 | struct 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 | //----------------------------------------------------------------------------- | ||
| 470 | struct 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 | //----------------------------------------------------------------------------- | ||
| 496 | struct 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 | //----------------------------------------------------------------------------- | ||
| 527 | struct 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 | //------------------------------------------------------------------------------ | ||
| 547 | Chuck_DL_Func * make_new_mfun( const char * t, const char * n, f_mfun mfun ); | ||
| 548 | Chuck_DL_Func * make_new_sfun( const char * t, const char * n, f_sfun sfun ); | ||
| 549 | Chuck_DL_Value * make_new_arg( const char * t, const char * n ); | ||
| 550 | Chuck_DL_Value * make_new_mvar( const char * t, const char * n, t_CKBOOL c = FALSE ); | ||
| 551 | Chuck_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 | //------------------------------------------------------------------------------ | ||
| 560 | union 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 | //----------------------------------------------------------------------------- | ||
| 584 | struct Chuck_DLL : public Chuck_VM_Object | ||
| 585 | { | ||
| 586 | public: | ||
| 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 | |||
| 605 | public: | ||
| 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 | |||
| 615 | protected: | ||
| 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 */ | ||
| 633 | namespace Chuck_DL_Api | ||
| 634 | { | ||
| 635 | typedef void * Object; | ||
| 636 | typedef void * Type; | ||
| 637 | typedef void * String; | ||
| 638 | |||
| 639 | struct Api | ||
| 640 | { | ||
| 641 | public: | ||
| 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 | |||
| 678 | private: | ||
| 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 | ||
| @@ -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 | |||
| 40 | using namespace std; | ||
| 41 | |||
| 42 | |||
| 43 | |||
| 44 | |||
| 45 | //----------------------------------------------------------------------------- | ||
| 46 | // function prototypes | ||
| 47 | //----------------------------------------------------------------------------- | ||
| 48 | t_CKBOOL emit_engine_emit_stmt_list( Chuck_Emitter * emit, a_Stmt_List list ); | ||
| 49 | t_CKBOOL emit_engine_emit_stmt( Chuck_Emitter * emit, a_Stmt stmt, t_CKBOOL pop = TRUE ); | ||
| 50 | t_CKBOOL emit_engine_emit_if( Chuck_Emitter * emit, a_Stmt_If stmt ); | ||
| 51 | t_CKBOOL emit_engine_emit_for( Chuck_Emitter * emit, a_Stmt_For stmt ); | ||
| 52 | t_CKBOOL emit_engine_emit_while( Chuck_Emitter * emit, a_Stmt_While stmt ); | ||
| 53 | t_CKBOOL emit_engine_emit_do_while( Chuck_Emitter * emit, a_Stmt_While stmt ); | ||
| 54 | t_CKBOOL emit_engine_emit_until( Chuck_Emitter * emit, a_Stmt_Until stmt ); | ||
| 55 | t_CKBOOL emit_engine_emit_do_until( Chuck_Emitter * emit, a_Stmt_Until stmt ); | ||
| 56 | t_CKBOOL emit_engine_emit_loop( Chuck_Emitter * emit, a_Stmt_Loop stmt ); | ||
| 57 | t_CKBOOL emit_engine_emit_break( Chuck_Emitter * emit, a_Stmt_Break br ); | ||
| 58 | t_CKBOOL emit_engine_emit_continue( Chuck_Emitter * emit, a_Stmt_Continue cont ); | ||
| 59 | t_CKBOOL emit_engine_emit_return( Chuck_Emitter * emit, a_Stmt_Return stmt ); | ||
| 60 | t_CKBOOL emit_engine_emit_switch( Chuck_Emitter * emit, a_Stmt_Switch stmt ); | ||
| 61 | t_CKBOOL emit_engine_emit_exp( Chuck_Emitter * emit, a_Exp exp, t_CKBOOL doAddRef = FALSE ); | ||
| 62 | t_CKBOOL emit_engine_emit_exp_binary( Chuck_Emitter * emit, a_Exp_Binary binary ); | ||
| 63 | t_CKBOOL emit_engine_emit_op( Chuck_Emitter * emit, ae_Operator op, a_Exp lhs, a_Exp rhs, a_Exp_Binary binary ); | ||
| 64 | t_CKBOOL emit_engine_emit_op_chuck( Chuck_Emitter * emit, a_Exp lhs, a_Exp rhs, a_Exp_Binary binary ); | ||
| 65 | t_CKBOOL emit_engine_emit_op_unchuck( Chuck_Emitter * emit, a_Exp lhs, a_Exp rhs ); | ||
| 66 | t_CKBOOL emit_engine_emit_op_upchuck( Chuck_Emitter * emit, a_Exp lhs, a_Exp rhs ); | ||
| 67 | t_CKBOOL emit_engine_emit_op_at_chuck( Chuck_Emitter * emit, a_Exp lhs, a_Exp rhs ); | ||
| 68 | t_CKBOOL emit_engine_emit_exp_unary( Chuck_Emitter * emit, a_Exp_Unary unary ); | ||
| 69 | t_CKBOOL emit_engine_emit_exp_primary( Chuck_Emitter * emit, a_Exp_Primary exp ); | ||
| 70 | t_CKBOOL emit_engine_emit_exp_cast( Chuck_Emitter * emit, a_Exp_Cast cast ); | ||
| 71 | t_CKBOOL emit_engine_emit_exp_postfix( Chuck_Emitter * emit, a_Exp_Postfix postfix ); | ||
| 72 | t_CKBOOL emit_engine_emit_exp_dur( Chuck_Emitter * emit, a_Exp_Dur dur ); | ||
| 73 | t_CKBOOL emit_engine_emit_exp_array( Chuck_Emitter * emit, a_Exp_Array array ); | ||
| 74 | t_CKBOOL emit_engine_emit_exp_func_call( Chuck_Emitter * emit, Chuck_Func * func, | ||
| 75 | Chuck_Type * type, int linepos, t_CKBOOL spork = FALSE ); | ||
| 76 | t_CKBOOL emit_engine_emit_exp_func_call( Chuck_Emitter * emit, a_Exp_Func_Call func_call, | ||
| 77 | t_CKBOOL spork = FALSE ); | ||
| 78 | t_CKBOOL emit_engine_emit_func_args( Chuck_Emitter * emit, a_Exp_Func_Call func_call ); | ||
| 79 | t_CKBOOL emit_engine_emit_exp_dot_member( Chuck_Emitter * emit, a_Exp_Dot_Member member ); | ||
| 80 | t_CKBOOL emit_engine_emit_exp_if( Chuck_Emitter * emit, a_Exp_If exp_if ); | ||
| 81 | t_CKBOOL emit_engine_emit_exp_decl( Chuck_Emitter * emit, a_Exp_Decl decl, t_CKBOOL first_exp ); | ||
| 82 | t_CKBOOL emit_engine_emit_array_lit( Chuck_Emitter * emit, a_Array_Sub array ); | ||
| 83 | t_CKBOOL emit_engine_emit_complex_lit( Chuck_Emitter * emit, a_Complex val ); | ||
| 84 | t_CKBOOL emit_engine_emit_polar_lit( Chuck_Emitter * emit, a_Polar val ); | ||
| 85 | t_CKBOOL emit_engine_emit_vec_lit( Chuck_Emitter * emit, a_Vec val ); | ||
| 86 | t_CKBOOL emit_engine_emit_code_segment( Chuck_Emitter * emit, a_Stmt_Code stmt, | ||
| 87 | t_CKBOOL push = TRUE ); | ||
| 88 | t_CKBOOL emit_engine_emit_func_def( Chuck_Emitter * emit, a_Func_Def func_def ); | ||
| 89 | t_CKBOOL emit_engine_emit_class_def( Chuck_Emitter * emit, a_Class_Def class_def ); | ||
| 90 | t_CKBOOL emit_engine_pre_constructor( Chuck_Emitter * emit, Chuck_Type * type ); | ||
| 91 | t_CKBOOL emit_engine_instantiate_object( Chuck_Emitter * emit, Chuck_Type * type, | ||
| 92 | a_Array_Sub array, t_CKBOOL is_ref ); | ||
| 93 | t_CKBOOL emit_engine_emit_spork( Chuck_Emitter * emit, a_Exp_Func_Call exp ); | ||
| 94 | t_CKBOOL emit_engine_emit_cast( Chuck_Emitter * emit, Chuck_Type * to, Chuck_Type * from ); | ||
| 95 | t_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 | //----------------------------------------------------------------------------- | ||
| 107 | Chuck_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 | //----------------------------------------------------------------------------- | ||
| 130 | t_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 | //----------------------------------------------------------------------------- | ||
| 151 | Chuck_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 | //----------------------------------------------------------------------------- | ||
| 261 | Chuck_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 | //----------------------------------------------------------------------------- | ||
| 331 | t_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 | //----------------------------------------------------------------------------- | ||
| 353 | t_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 | //----------------------------------------------------------------------------- | ||
| 491 | t_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 | //----------------------------------------------------------------------------- | ||
| 587 | t_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 | //----------------------------------------------------------------------------- | ||
| 736 | t_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 | //----------------------------------------------------------------------------- | ||
| 839 | t_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 | //----------------------------------------------------------------------------- | ||
| 938 | t_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 | //----------------------------------------------------------------------------- | ||
| 1039 | t_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 | //----------------------------------------------------------------------------- | ||
| 1130 | t_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 | //----------------------------------------------------------------------------- | ||
| 1237 | t_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 | //----------------------------------------------------------------------------- | ||
| 1255 | t_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 | //----------------------------------------------------------------------------- | ||
| 1273 | t_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 | //----------------------------------------------------------------------------- | ||
| 1296 | t_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 | //----------------------------------------------------------------------------- | ||
| 1308 | t_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 | //----------------------------------------------------------------------------- | ||
| 1411 | t_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 | //----------------------------------------------------------------------------- | ||
| 1514 | t_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 | //----------------------------------------------------------------------------- | ||
| 2430 | t_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 | //----------------------------------------------------------------------------- | ||
| 2553 | t_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 | //----------------------------------------------------------------------------- | ||
| 2583 | t_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 | //----------------------------------------------------------------------------- | ||
| 2615 | t_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 | //----------------------------------------------------------------------------- | ||
| 2701 | t_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 | //----------------------------------------------------------------------------- | ||
| 2845 | t_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 | //----------------------------------------------------------------------------- | ||
| 3018 | t_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 | //----------------------------------------------------------------------------- | ||
| 3049 | t_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 | //----------------------------------------------------------------------------- | ||
| 3069 | t_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 | //----------------------------------------------------------------------------- | ||
| 3089 | t_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 | //----------------------------------------------------------------------------- | ||
| 3116 | t_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 | //----------------------------------------------------------------------------- | ||
| 3136 | t_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 | //----------------------------------------------------------------------------- | ||
| 3185 | t_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 | //----------------------------------------------------------------------------- | ||
| 3235 | t_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 | //----------------------------------------------------------------------------- | ||
| 3262 | t_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 | //----------------------------------------------------------------------------- | ||
| 3367 | t_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 | //----------------------------------------------------------------------------- | ||
| 3432 | t_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 | //----------------------------------------------------------------------------- | ||
| 3453 | t_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 | //----------------------------------------------------------------------------- | ||
| 3487 | t_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 | //----------------------------------------------------------------------------- | ||
| 3593 | check_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 | //----------------------------------------------------------------------------- | ||
| 3660 | t_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 | //----------------------------------------------------------------------------- | ||
| 3831 | t_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 | //----------------------------------------------------------------------------- | ||
| 3904 | t_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 | //----------------------------------------------------------------------------- | ||
| 3930 | t_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 | //----------------------------------------------------------------------------- | ||
| 3959 | t_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 | //----------------------------------------------------------------------------- | ||
| 4000 | t_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 | //----------------------------------------------------------------------------- | ||
| 4288 | t_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 | //----------------------------------------------------------------------------- | ||
| 4316 | t_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 | //----------------------------------------------------------------------------- | ||
| 4493 | t_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 | //----------------------------------------------------------------------------- | ||
| 4627 | t_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 | //----------------------------------------------------------------------------- | ||
| 4773 | t_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 | //----------------------------------------------------------------------------- | ||
| 4900 | void 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 | //----------------------------------------------------------------------------- | ||
| 4936 | void 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 | //----------------------------------------------------------------------------- | ||
| 4978 | t_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.
| @@ -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 | ||
| 43 | struct Chuck_Instr; | ||
| 44 | struct Chuck_Instr_Goto; | ||
| 45 | struct Chuck_VM_Code; | ||
| 46 | struct Chuck_VM_Shred; | ||
| 47 | |||
| 48 | |||
| 49 | |||
| 50 | |||
| 51 | //----------------------------------------------------------------------------- | ||
| 52 | // name: struct Chuck_Code | ||
| 53 | // desc: ... | ||
| 54 | //----------------------------------------------------------------------------- | ||
| 55 | struct Chuck_Code | ||
| 56 | { | ||
| 57 | public: | ||
| 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 | //----------------------------------------------------------------------------- | ||
| 98 | struct 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 | ||
| 157 | Chuck_Emitter * emit_engine_init( Chuck_Env * env ); | ||
| 158 | // shutdown and free the emitter | ||
| 159 | t_CKBOOL emit_engine_shutdown( Chuck_Emitter *& emit ); | ||
| 160 | // emit a program into vm code | ||
| 161 | Chuck_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 | ||
| 165 | Chuck_VM_Code * emit_to_code( Chuck_Code * in, | ||
| 166 | Chuck_VM_Code * out = NULL, | ||
| 167 | t_CKBOOL dump = FALSE ); | ||
| 168 | |||
| 169 | // NOT USED: ... | ||
| 170 | t_CKBOOL emit_engine_addr_map( Chuck_Emitter * emit, Chuck_VM_Shred * shred ); | ||
| 171 | t_CKBOOL emit_engine_resolve( ); | ||
| 172 | |||
| 173 | |||
| 174 | |||
| 175 | |||
| 176 | #endif | ||
| @@ -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 | ||
| 45 | int EM_tokPos = 0; | ||
| 46 | int EM_lineNum = 1; | ||
| 47 | int EM_extLineNum = 1; | ||
| 48 | t_CKBOOL anyErrors= FALSE; | ||
| 49 | |||
| 50 | // local global | ||
| 51 | static const char * fileName = ""; | ||
| 52 | static int lineNum = 1; | ||
| 53 | static char g_buffer[1024] = ""; | ||
| 54 | static const size_t LASTERROR_SIZE = 1024; | ||
| 55 | static char g_lasterror[LASTERROR_SIZE] = "[chuck]: (no error)"; | ||
| 56 | static size_t g_lasterrorIndex = strlen(g_lasterror); | ||
| 57 | // log globals | ||
| 58 | int g_loglevel = CK_LOG_CORE; | ||
| 59 | int g_logstack = 0; | ||
| 60 | XMutex g_logmutex; | ||
| 61 | |||
| 62 | // more local globals | ||
| 63 | static const size_t g_buffer2_size = 1024; | ||
| 64 | static char g_buffer2[g_buffer2_size] = ""; | ||
| 65 | std::stringstream g_stdout_stream; | ||
| 66 | std::stringstream g_stderr_stream; | ||
| 67 | |||
| 68 | // local global callbacks | ||
| 69 | void (*g_stdout_callback)(const char *) = NULL; | ||
| 70 | void (*g_stderr_callback)(const char *) = NULL; | ||
| 71 | |||
| 72 | void 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 | |||
| 88 | void 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 | |||
| 104 | void 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 | |||
| 126 | void 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 | |||
| 149 | void 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 | |||
| 162 | void 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 | |||
| 176 | void 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 | |||
| 185 | void 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 | ||
| 194 | extern "C++" { | ||
| 195 | |||
| 196 | ChuckOutStream::ChuckOutStream( bool isErr ) | ||
| 197 | { | ||
| 198 | m_callback = NULL; | ||
| 199 | m_isErr = isErr; | ||
| 200 | } | ||
| 201 | |||
| 202 | |||
| 203 | ChuckOutStream::~ChuckOutStream() | ||
| 204 | { | ||
| 205 | } | ||
| 206 | |||
| 207 | |||
| 208 | ChuckOutStream& 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 | |||
| 219 | ChuckOutStream& ChuckOutStream::operator<<( const char * val ) | ||
| 220 | { | ||
| 221 | m_stream << val; | ||
| 222 | return *this; | ||
| 223 | } | ||
| 224 | |||
| 225 | |||
| 226 | ChuckOutStream& ChuckOutStream::operator<<( const double val ) | ||
| 227 | { | ||
| 228 | m_stream << val; | ||
| 229 | return *this; | ||
| 230 | } | ||
| 231 | |||
| 232 | |||
| 233 | ChuckOutStream& ChuckOutStream::operator<<( const float val ) | ||
| 234 | { | ||
| 235 | m_stream << val; | ||
| 236 | return *this; | ||
| 237 | } | ||
| 238 | |||
| 239 | |||
| 240 | ChuckOutStream& ChuckOutStream::operator<<( const unsigned long long val ) | ||
| 241 | { | ||
| 242 | m_stream << val; | ||
| 243 | return *this; | ||
| 244 | } | ||
| 245 | |||
| 246 | |||
| 247 | ChuckOutStream& ChuckOutStream::operator<<( const long long val ) | ||
| 248 | { | ||
| 249 | m_stream << val; | ||
| 250 | return *this; | ||
| 251 | } | ||
| 252 | |||
| 253 | |||
| 254 | ChuckOutStream& ChuckOutStream::operator<<( const unsigned long val ) | ||
| 255 | { | ||
| 256 | m_stream << val; | ||
| 257 | return *this; | ||
| 258 | } | ||
| 259 | |||
| 260 | |||
| 261 | ChuckOutStream& ChuckOutStream::operator<<( const long val ) | ||
| 262 | { | ||
| 263 | m_stream << val; | ||
| 264 | return *this; | ||
| 265 | } | ||
| 266 | |||
| 267 | |||
| 268 | ChuckOutStream& ChuckOutStream::operator<<( const unsigned int val ) | ||
| 269 | { | ||
| 270 | m_stream << val; | ||
| 271 | return *this; | ||
| 272 | } | ||
| 273 | |||
| 274 | |||
| 275 | ChuckOutStream& ChuckOutStream::operator<<( const int val ) | ||
| 276 | { | ||
| 277 | m_stream << val; | ||
| 278 | return *this; | ||
| 279 | } | ||
| 280 | |||
| 281 | |||
| 282 | ChuckOutStream& ChuckOutStream::operator<<( const bool val ) | ||
| 283 | { | ||
| 284 | m_stream << val; | ||
| 285 | return *this; | ||
| 286 | } | ||
| 287 | |||
| 288 | |||
| 289 | |||
| 290 | |||
| 291 | |||
| 292 | void ChuckOutStream::set_callback( void (*callback)( const char * ) ) | ||
| 293 | { | ||
| 294 | m_callback = callback; | ||
| 295 | } | ||
| 296 | |||
| 297 | |||
| 298 | void 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 | |||
| 326 | ChuckOutStream g_ck_stdoutstream( FALSE ); | ||
| 327 | ChuckOutStream g_ck_stderrstream( TRUE ); | ||
| 328 | |||
| 329 | } | ||
| 330 | #endif | ||
| 331 | |||
| 332 | |||
| 333 | |||
| 334 | |||
| 335 | // name | ||
| 336 | static 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 | ||
| 352 | typedef struct intList {int i; struct intList *rest;} *IntList; | ||
| 353 | static IntList linePos=NULL; | ||
| 354 | |||
| 355 | |||
| 356 | static 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 | ||
| 372 | static 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 | ||
| 381 | void 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 '/' | ||
| 391 | const 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' | ||
| 401 | const 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 | |||
| 409 | void EM_reset_msg() | ||
| 410 | { | ||
| 411 | g_lasterror[0] = '\0'; | ||
| 412 | g_lasterrorIndex = 0; | ||
| 413 | } | ||
| 414 | |||
| 415 | // [%s]:line(%d).char(%d): | ||
| 416 | void 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): | ||
| 459 | void 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): | ||
| 495 | void 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 | // | ||
| 531 | void 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 | ||
| 556 | void 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 | ||
| 585 | void 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 | ||
| 596 | void EM_pushlog() | ||
| 597 | { | ||
| 598 | g_logstack++; | ||
| 599 | } | ||
| 600 | |||
| 601 | // pop log | ||
| 602 | void EM_poplog() | ||
| 603 | { | ||
| 604 | g_logstack--; | ||
| 605 | if( g_logstack < 0 ) g_logstack = 0; | ||
| 606 | } | ||
| 607 | |||
| 608 | // prepare new file | ||
| 609 | t_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 | ||
| 635 | void 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 | ||
| 647 | const char * EM_lasterror() | ||
| 648 | { | ||
| 649 | return g_lasterror; | ||
| 650 | } | ||
| @@ -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) | ||
| 42 | extern "C" { | ||
| 43 | #endif | ||
| 44 | |||
| 45 | |||
| 46 | extern t_CKBOOL EM_anyErrors; | ||
| 47 | extern int EM_tokPos; | ||
| 48 | extern 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) | ||
| 52 | extern int EM_extLineNum; | ||
| 53 | |||
| 54 | void 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 | ||
| 74 | void ck_fprintf_stdout( const char * format, ... ); | ||
| 75 | void ck_fprintf_stderr( const char * format, ... ); | ||
| 76 | void ck_fflush_stdout(); | ||
| 77 | void ck_fflush_stderr(); | ||
| 78 | void ck_vfprintf_stdout( const char * format, va_list args ); | ||
| 79 | void ck_vfprintf_stderr( const char * format, va_list args ); | ||
| 80 | |||
| 81 | // callbacks | ||
| 82 | void ck_set_stdout_callback( void (*callback)(const char *) ); | ||
| 83 | void 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 | ||
| 94 | extern "C++" { | ||
| 95 | #include <sstream> | ||
| 96 | |||
| 97 | class ChuckOutStream | ||
| 98 | { | ||
| 99 | public: | ||
| 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 | |||
| 119 | private: | ||
| 120 | void flush(); | ||
| 121 | std::stringstream m_stream; | ||
| 122 | void (*m_callback)(const char *); | ||
| 123 | bool m_isErr; | ||
| 124 | }; | ||
| 125 | |||
| 126 | |||
| 127 | extern ChuckOutStream g_ck_stdoutstream; | ||
| 128 | extern 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 | |||
| 149 | void EM_log( int, c_constr, ... ); | ||
| 150 | void EM_setlog( int ); | ||
| 151 | void EM_pushlog(); | ||
| 152 | void EM_poplog(); | ||
| 153 | |||
| 154 | // actual level | ||
| 155 | extern int g_loglevel; | ||
| 156 | // macro to compare | ||
| 157 | #define DO_LOG(x) ( x <= g_loglevel ) | ||
| 158 | |||
| 159 | void EM_error( int, c_constr, ... ); | ||
| 160 | void EM_error2( int, c_constr, ... ); | ||
| 161 | void EM_error2b( int, c_constr, ... ); | ||
| 162 | void EM_error3( c_constr, ... ); | ||
| 163 | void EM_impossible( c_constr, ... ); | ||
| 164 | t_CKBOOL EM_reset( c_constr filename, FILE * fd ); | ||
| 165 | void EM_change_file( c_constr filename ); | ||
| 166 | const char * EM_lasterror(); | ||
| 167 | void EM_reset_msg(); | ||
| 168 | |||
| 169 | const char * mini( const char * str ); | ||
| 170 | const char * mini_type( const char * str ); | ||
| 171 | |||
| 172 | #if defined(_cplusplus) || defined(__cplusplus) | ||
| 173 | } | ||
| 174 | #endif | ||
| 175 | |||
| 176 | |||
| 177 | #endif | ||
| @@ -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" | ||
| 33 | using namespace std; | ||
| 34 | |||
| 35 | |||
| 36 | |||
| 37 | |||
| 38 | //----------------------------------------------------------------------------- | ||
| 39 | // name: Chuck_Frame() | ||
| 40 | // desc: ... | ||
| 41 | //----------------------------------------------------------------------------- | ||
| 42 | Chuck_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 | //----------------------------------------------------------------------------- | ||
| 59 | Chuck_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 | //----------------------------------------------------------------------------- | ||
| 91 | void 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 | //----------------------------------------------------------------------------- | ||
| 103 | void 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 | //----------------------------------------------------------------------------- | ||
| 136 | void 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 | } | ||
| @@ -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 | //----------------------------------------------------------------------------- | ||
| 45 | struct 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 | //----------------------------------------------------------------------------- | ||
| 73 | struct 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 | |||
| 84 | public: | ||
| 85 | Chuck_Frame(); | ||
| 86 | ~Chuck_Frame() { } | ||
| 87 | |||
| 88 | public: | ||
| 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 | ||
| @@ -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> | ||
| 46 | using namespace std; | ||
| 47 | |||
| 48 | |||
| 49 | |||
| 50 | |||
| 51 | //----------------------------------------------------------------------------- | ||
| 52 | // name: Chuck_Instr() | ||
| 53 | // desc: base class constructor | ||
| 54 | //----------------------------------------------------------------------------- | ||
| 55 | Chuck_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 | //----------------------------------------------------------------------------- | ||
| 67 | const 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 | //----------------------------------------------------------------------------- | ||
| 79 | void 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 | //----------------------------------------------------------------------------- | ||
| 90 | static 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 | //----------------------------------------------------------------------------- | ||
| 109 | void 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 | //----------------------------------------------------------------------------- | ||
| 123 | void 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 | //----------------------------------------------------------------------------- | ||
| 144 | void 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 | //----------------------------------------------------------------------------- | ||
| 168 | void 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 | //----------------------------------------------------------------------------- | ||
| 189 | void 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 | //----------------------------------------------------------------------------- | ||
| 213 | void 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 | //----------------------------------------------------------------------------- | ||
| 226 | void 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 | //----------------------------------------------------------------------------- | ||
| 239 | void 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 | //----------------------------------------------------------------------------- | ||
| 253 | void 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 | //----------------------------------------------------------------------------- | ||
| 267 | void 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 | //----------------------------------------------------------------------------- | ||
| 281 | void 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 | //----------------------------------------------------------------------------- | ||
| 295 | void 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 | //----------------------------------------------------------------------------- | ||
| 309 | void 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; | ||
| 317 | div_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 | |||
| 324 | done: | ||
| 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 | //----------------------------------------------------------------------------- | ||
| 337 | void 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; | ||
| 345 | div_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 | |||
| 352 | done: | ||
| 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 | //----------------------------------------------------------------------------- | ||
| 367 | void 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 | //----------------------------------------------------------------------------- | ||
| 381 | void 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 | //----------------------------------------------------------------------------- | ||
| 395 | void 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 | //----------------------------------------------------------------------------- | ||
| 409 | void 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 | //----------------------------------------------------------------------------- | ||
| 423 | void 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 | //----------------------------------------------------------------------------- | ||
| 438 | void 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 | //----------------------------------------------------------------------------- | ||
| 452 | void 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 | //----------------------------------------------------------------------------- | ||
| 466 | void 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 | //----------------------------------------------------------------------------- | ||
| 482 | void 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 | //----------------------------------------------------------------------------- | ||
| 501 | void 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 | //----------------------------------------------------------------------------- | ||
| 520 | void 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 | //----------------------------------------------------------------------------- | ||
| 539 | void 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 | //----------------------------------------------------------------------------- | ||
| 558 | void 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 | //----------------------------------------------------------------------------- | ||
| 584 | void 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 | //----------------------------------------------------------------------------- | ||
| 609 | void 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 | //----------------------------------------------------------------------------- | ||
| 632 | void 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 | //----------------------------------------------------------------------------- | ||
| 655 | void 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 | //----------------------------------------------------------------------------- | ||
| 678 | void 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 | //----------------------------------------------------------------------------- | ||
| 697 | void 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 | //----------------------------------------------------------------------------- | ||
| 717 | void 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 | //----------------------------------------------------------------------------- | ||
| 736 | void 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 | //----------------------------------------------------------------------------- | ||
| 758 | void 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 | //----------------------------------------------------------------------------- | ||
| 780 | void 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 | //----------------------------------------------------------------------------- | ||
| 802 | void 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 | //----------------------------------------------------------------------------- | ||
| 830 | void 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 | //----------------------------------------------------------------------------- | ||
| 858 | void 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 | //----------------------------------------------------------------------------- | ||
| 886 | void 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 | //----------------------------------------------------------------------------- | ||
| 910 | void 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 | //----------------------------------------------------------------------------- | ||
| 934 | void 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 | //----------------------------------------------------------------------------- | ||
| 958 | void 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 | //----------------------------------------------------------------------------- | ||
| 987 | void 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 | //----------------------------------------------------------------------------- | ||
| 1016 | void 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 | //----------------------------------------------------------------------------- | ||
| 1048 | void 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 | //----------------------------------------------------------------------------- | ||
| 1063 | void 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 | //----------------------------------------------------------------------------- | ||
| 1078 | void 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 | //----------------------------------------------------------------------------- | ||
| 1093 | void 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 | //----------------------------------------------------------------------------- | ||
| 1108 | void 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; | ||
| 1117 | div_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 | |||
| 1124 | done: | ||
| 1125 | // do something! | ||
| 1126 | shred->is_running = FALSE; | ||
| 1127 | shred->is_done = TRUE; | ||
| 1128 | } | ||
| 1129 | |||
| 1130 | |||
| 1131 | |||
| 1132 | //----------------------------------------------------------------------------- | ||
| 1133 | // name: execute() | ||
| 1134 | // desc: ... | ||
| 1135 | //----------------------------------------------------------------------------- | ||
| 1136 | void 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 | //----------------------------------------------------------------------------- | ||
| 1155 | void 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 | //----------------------------------------------------------------------------- | ||
| 1174 | void 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 | //----------------------------------------------------------------------------- | ||
| 1193 | void 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 | //----------------------------------------------------------------------------- | ||
| 1212 | void 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 | //----------------------------------------------------------------------------- | ||
| 1232 | void 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 | //----------------------------------------------------------------------------- | ||
| 1253 | void 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 | //----------------------------------------------------------------------------- | ||
| 1274 | void 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 | //----------------------------------------------------------------------------- | ||
| 1300 | void 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 | //----------------------------------------------------------------------------- | ||
| 1330 | void 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 | //----------------------------------------------------------------------------- | ||
| 1362 | void 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 | //----------------------------------------------------------------------------- | ||
| 1394 | void 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 | //----------------------------------------------------------------------------- | ||
| 1415 | void 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 | //----------------------------------------------------------------------------- | ||
| 1436 | void 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 | //----------------------------------------------------------------------------- | ||
| 1458 | void 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 | //----------------------------------------------------------------------------- | ||
| 1480 | void 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 | //----------------------------------------------------------------------------- | ||
| 1502 | void 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 | //----------------------------------------------------------------------------- | ||
| 1524 | void 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 | //----------------------------------------------------------------------------- | ||
| 1547 | void 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 | //----------------------------------------------------------------------------- | ||
| 1570 | void 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 | //----------------------------------------------------------------------------- | ||
| 1593 | void 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 | //----------------------------------------------------------------------------- | ||
| 1618 | void 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 | |||
| 1647 | null_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 | |||
| 1654 | done: | ||
| 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 | //----------------------------------------------------------------------------- | ||
| 1667 | void 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 | |||
| 1692 | null_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 | |||
| 1699 | done: | ||
| 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 | //----------------------------------------------------------------------------- | ||
| 1712 | void 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 | |||
| 1741 | null_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 | |||
| 1748 | done: | ||
| 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 | //----------------------------------------------------------------------------- | ||
| 1761 | void 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 | |||
| 1790 | null_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 | |||
| 1797 | done: | ||
| 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 | //----------------------------------------------------------------------------- | ||
| 1810 | void 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 | |||
| 1839 | null_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 | |||
| 1846 | done: | ||
| 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 | //----------------------------------------------------------------------------- | ||
| 1859 | void 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 | |||
| 1888 | null_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 | |||
| 1895 | done: | ||
| 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 | //----------------------------------------------------------------------------- | ||
| 1908 | void 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 | |||
| 1933 | null_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 | |||
| 1940 | done: | ||
| 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 | //----------------------------------------------------------------------------- | ||
| 1953 | void 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 | |||
| 1978 | null_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 | |||
| 1985 | done: | ||
| 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 | //----------------------------------------------------------------------------- | ||
| 2000 | void 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 | //----------------------------------------------------------------------------- | ||
| 2015 | void 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 | //----------------------------------------------------------------------------- | ||
| 2030 | void 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 | //----------------------------------------------------------------------------- | ||
| 2046 | void 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 | //----------------------------------------------------------------------------- | ||
| 2061 | void 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 | //----------------------------------------------------------------------------- | ||
| 2076 | void 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 | //----------------------------------------------------------------------------- | ||
| 2093 | void 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 | //----------------------------------------------------------------------------- | ||
| 2108 | void 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 | //----------------------------------------------------------------------------- | ||
| 2123 | void 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 | //----------------------------------------------------------------------------- | ||
| 2139 | void 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 | //----------------------------------------------------------------------------- | ||
| 2154 | void 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 | //----------------------------------------------------------------------------- | ||
| 2170 | void 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 | //----------------------------------------------------------------------------- | ||
| 2186 | void 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 | //----------------------------------------------------------------------------- | ||
| 2201 | void 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 | //----------------------------------------------------------------------------- | ||
| 2217 | void 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 | //----------------------------------------------------------------------------- | ||
| 2233 | void 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 | //----------------------------------------------------------------------------- | ||
| 2249 | void 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 | //----------------------------------------------------------------------------- | ||
| 2265 | void 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 | //----------------------------------------------------------------------------- | ||
| 2281 | void 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 | //----------------------------------------------------------------------------- | ||
| 2325 | void 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 | //----------------------------------------------------------------------------- | ||
| 2341 | void 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 | //----------------------------------------------------------------------------- | ||
| 2371 | void 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 | //----------------------------------------------------------------------------- | ||
| 2389 | void 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 | //----------------------------------------------------------------------------- | ||
| 2404 | void 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 | //----------------------------------------------------------------------------- | ||
| 2419 | void 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 | //----------------------------------------------------------------------------- | ||
| 2434 | void 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 | //----------------------------------------------------------------------------- | ||
| 2453 | void 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 | //----------------------------------------------------------------------------- | ||
| 2468 | void 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 | //----------------------------------------------------------------------------- | ||
| 2483 | void 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 | //----------------------------------------------------------------------------- | ||
| 2498 | void 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 | //----------------------------------------------------------------------------- | ||
| 2513 | void 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 | //----------------------------------------------------------------------------- | ||
| 2528 | void 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 | //----------------------------------------------------------------------------- | ||
| 2543 | void 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 | //----------------------------------------------------------------------------- | ||
| 2560 | void 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 | //----------------------------------------------------------------------------- | ||
| 2575 | void 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 | //----------------------------------------------------------------------------- | ||
| 2590 | void 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 | //----------------------------------------------------------------------------- | ||
| 2605 | void 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 | //----------------------------------------------------------------------------- | ||
| 2620 | void 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 | //----------------------------------------------------------------------------- | ||
| 2635 | void 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 | //----------------------------------------------------------------------------- | ||
| 2650 | void 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 | //----------------------------------------------------------------------------- | ||
| 2663 | void 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 | //----------------------------------------------------------------------------- | ||
| 2676 | void 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 | //----------------------------------------------------------------------------- | ||
| 2689 | void 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 | //----------------------------------------------------------------------------- | ||
| 2704 | void 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 | //----------------------------------------------------------------------------- | ||
| 2719 | void 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 | //----------------------------------------------------------------------------- | ||
| 2734 | void 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 | //----------------------------------------------------------------------------- | ||
| 2749 | void 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 | //----------------------------------------------------------------------------- | ||
| 2764 | void 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 | //----------------------------------------------------------------------------- | ||
| 2779 | void 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 | //----------------------------------------------------------------------------- | ||
| 2803 | void 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 | //----------------------------------------------------------------------------- | ||
| 2830 | void 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 | //----------------------------------------------------------------------------- | ||
| 2844 | void 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 | //----------------------------------------------------------------------------- | ||
| 2858 | void 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 | //----------------------------------------------------------------------------- | ||
| 2872 | void 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 | //----------------------------------------------------------------------------- | ||
| 2886 | void 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 | //----------------------------------------------------------------------------- | ||
| 2900 | void 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 | //----------------------------------------------------------------------------- | ||
| 2914 | void 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 | //----------------------------------------------------------------------------- | ||
| 2928 | void 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 | //----------------------------------------------------------------------------- | ||
| 2943 | void 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 | //----------------------------------------------------------------------------- | ||
| 2958 | void 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 | //----------------------------------------------------------------------------- | ||
| 2973 | void 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 | //----------------------------------------------------------------------------- | ||
| 2988 | void 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 | //----------------------------------------------------------------------------- | ||
| 3005 | void 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 | //----------------------------------------------------------------------------- | ||
| 3019 | void 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 | //----------------------------------------------------------------------------- | ||
| 3033 | void 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 | //----------------------------------------------------------------------------- | ||
| 3047 | void 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 | //----------------------------------------------------------------------------- | ||
| 3061 | void 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 | //----------------------------------------------------------------------------- | ||
| 3075 | void 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 | //----------------------------------------------------------------------------- | ||
| 3089 | void 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 | //----------------------------------------------------------------------------- | ||
| 3104 | void 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 | //----------------------------------------------------------------------------- | ||
| 3119 | void 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 | //----------------------------------------------------------------------------- | ||
| 3134 | void 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 | //----------------------------------------------------------------------------- | ||
| 3149 | void 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 | //----------------------------------------------------------------------------- | ||
| 3164 | void 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 | //----------------------------------------------------------------------------- | ||
| 3178 | void 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 | //----------------------------------------------------------------------------- | ||
| 3194 | void 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 | //----------------------------------------------------------------------------- | ||
| 3210 | void 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 | //----------------------------------------------------------------------------- | ||
| 3227 | void 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 | //----------------------------------------------------------------------------- | ||
| 3244 | void 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 | //----------------------------------------------------------------------------- | ||
| 3261 | void 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 | //----------------------------------------------------------------------------- | ||
| 3281 | void 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 | //----------------------------------------------------------------------------- | ||
| 3295 | void 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 | //----------------------------------------------------------------------------- | ||
| 3311 | void 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 | //----------------------------------------------------------------------------- | ||
| 3323 | void 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 | //----------------------------------------------------------------------------- | ||
| 3335 | void 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 | //----------------------------------------------------------------------------- | ||
| 3353 | void 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 | //----------------------------------------------------------------------------- | ||
| 3371 | void 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 | //----------------------------------------------------------------------------- | ||
| 3389 | void 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 | //----------------------------------------------------------------------------- | ||
| 3408 | void 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 | //----------------------------------------------------------------------------- | ||
| 3428 | void 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 | //----------------------------------------------------------------------------- | ||
| 3449 | void 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 | //----------------------------------------------------------------------------- | ||
| 3469 | void 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 | //----------------------------------------------------------------------------- | ||
| 3489 | void 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 | //----------------------------------------------------------------------------- | ||
| 3510 | void 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 | //----------------------------------------------------------------------------- | ||
| 3532 | void 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 | //----------------------------------------------------------------------------- | ||
| 3555 | void 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 | |||
| 3586 | static Chuck_Instr_Func_Call g_func_call; | ||
| 3587 | static Chuck_Instr_Func_Call_Member g_func_call_member( 0 ); | ||
| 3588 | //----------------------------------------------------------------------------- | ||
| 3589 | // name: call_pre_constructor() | ||
| 3590 | // desc: ... | ||
| 3591 | //----------------------------------------------------------------------------- | ||
| 3592 | inline 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 | //----------------------------------------------------------------------------- | ||
| 3621 | void 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 | //----------------------------------------------------------------------------- | ||
| 3633 | t_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 | |||
| 3696 | out_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 | //----------------------------------------------------------------------------- | ||
| 3717 | Chuck_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 | //----------------------------------------------------------------------------- | ||
| 3730 | Chuck_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 | //----------------------------------------------------------------------------- | ||
| 3745 | Chuck_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 | |||
| 3807 | out_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 | |||
| 3814 | error: | ||
| 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 | //----------------------------------------------------------------------------- | ||
| 3830 | inline 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 | |||
| 3847 | error: | ||
| 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 | //----------------------------------------------------------------------------- | ||
| 3861 | void 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 | //----------------------------------------------------------------------------- | ||
| 3873 | const 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 | //----------------------------------------------------------------------------- | ||
| 3887 | const 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.
This diff is large: its 4048 lines aren’t shown here.
This diff is large: its 1950 lines aren’t shown here.
This diff is large: its 205 lines aren’t shown here.
This diff is large: its 4861 lines aren’t shown here.
This diff is large: its 482 lines aren’t shown here.
This diff is large: its 3286 lines aren’t shown here.
This diff is large: its 709 lines aren’t shown here.
This diff is large: its 748 lines aren’t shown here.
This diff is large: its 102 lines aren’t shown here.
This diff is large: its 231 lines aren’t shown here.
This diff is large: its 154 lines aren’t shown here.
This diff is large: its 2733 lines aren’t shown here.
This diff is large: its 72 lines aren’t shown here.
This diff is large: its 2261 lines aren’t shown here.
This diff is large: its 579 lines aren’t shown here.
This diff is large: its 303 lines aren’t shown here.
This diff is large: its 199 lines aren’t shown here.
This diff is large: its 144 lines aren’t shown here.
This diff is large: its 89 lines aren’t shown here.
This diff is large: its 222 lines aren’t shown here.
This diff is large: its 77 lines aren’t shown here.
This diff is large: its 6489 lines aren’t shown here.
This diff is large: its 971 lines aren’t shown here.
This diff is large: its 1544 lines aren’t shown here.
This diff is large: its 200 lines aren’t shown here.
This diff is large: its 78 lines aren’t shown here.
This diff is large: its 63 lines aren’t shown here.
This diff is large: its 2761 lines aren’t shown here.
This diff is large: its 756 lines aren’t shown here.
This diff is large: its 2633 lines aren’t shown here.
This diff is large: its 204 lines aren’t shown here.
This diff is large: its 235 lines aren’t shown here.
This diff is large: its 1033 lines aren’t shown here.
This diff is large: its 173 lines aren’t shown here.
This diff is large: its 347 lines aren’t shown here.
This diff is large: its 65 lines aren’t shown here.
This diff is large: its 182 lines aren’t shown here.
This diff is large: its 201 lines aren’t shown here.
This diff is large: its 354 lines aren’t shown here.
This diff is large: its 257 lines aren’t shown here.
This diff is large: its 46 lines aren’t shown here.
This diff is large: its 64 lines aren’t shown here.
This diff is large: its 861 lines aren’t shown here.
This diff is large: its 81 lines aren’t shown here.
This diff is large: its 146 lines aren’t shown here.
This diff is large: its 31 lines aren’t shown here.
This diff is large: its 144 lines aren’t shown here.
This diff is large: its 146 lines aren’t shown here.
This diff is large: its 1082 lines aren’t shown here.
This diff is large: its 36 lines aren’t shown here.
This diff is large: its 249 lines aren’t shown here.
This diff is large: its 492 lines aren’t shown here.
This diff is large: its 1401 lines aren’t shown here.
This diff is large: its 189 lines aren’t shown here.
This diff is large: its 59 lines aren’t shown here.
This diff is large: its 1011 lines aren’t shown here.
This diff is large: its 279 lines aren’t shown here.
This diff is large: its 30 lines aren’t shown here.
This diff is large: its 236 lines aren’t shown here.
This diff is large: its 185 lines aren’t shown here.
This diff is large: its 130 lines aren’t shown here.
This diff is large: its 84 lines aren’t shown here.
This diff is large: its 39 lines aren’t shown here.
This diff is large: its 349 lines aren’t shown here.
This diff is large: its 227 lines aren’t shown here.
This diff is large: its 129 lines aren’t shown here.
This diff is large: its 2297 lines aren’t shown here.
This diff is large: its 28 lines aren’t shown here.
This diff is large: its 53 lines aren’t shown here.
This diff is large: its 74 lines aren’t shown here.
This diff is large: its 20 lines aren’t shown here.
This diff is large: its 288 lines aren’t shown here.
This diff is large: its 813 lines aren’t shown here.
This diff is large: its 667 lines aren’t shown here.
This diff is large: its 502 lines aren’t shown here.
This diff is large: its 216 lines aren’t shown here.
This diff is large: its 156 lines aren’t shown here.
This diff is large: its 67 lines aren’t shown here.
This diff is large: its 1740 lines aren’t shown here.
This diff is large: its 51 lines aren’t shown here.
This diff is large: its 126 lines aren’t shown here.
This diff is large: its 77 lines aren’t shown here.
This diff is large: its 277 lines aren’t shown here.
This diff is large: its 352 lines aren’t shown here.
This diff is large: its 78 lines aren’t shown here.
This diff is large: its 2323 lines aren’t shown here.
This diff is large: its 363 lines aren’t shown here.
This diff is large: its 1527 lines aren’t shown here.
This diff is large: its 46 lines aren’t shown here.
This diff is large: its 3763 lines aren’t shown here.
This diff is large: its 46 lines aren’t shown here.
This diff is large: its 2695 lines aren’t shown here.
This diff is large: its 239 lines aren’t shown here.
This diff is large: its 1760 lines aren’t shown here.
This diff is large: its 113 lines aren’t shown here.
This diff is large: its 27020 lines aren’t shown here.
This diff is large: its 6623 lines aren’t shown here.
This diff is large: its 4965 lines aren’t shown here.
This diff is large: its 257 lines aren’t shown here.
This diff is large: its 221 lines aren’t shown here.
This diff is large: its 63 lines aren’t shown here.
This diff is large: its 778 lines aren’t shown here.
This diff is large: its 101 lines aren’t shown here.
This diff is large: its 1663 lines aren’t shown here.
This diff is large: its 80 lines aren’t shown here.
This diff is large: its 405 lines aren’t shown here.
This diff is large: its 41 lines aren’t shown here.
This diff is large: its 1986 lines aren’t shown here.
This diff is large: its 144 lines aren’t shown here.
This diff is large: its 1023 lines aren’t shown here.
This diff is large: its 699 lines aren’t shown here.
This diff is large: its 211 lines aren’t shown here.
This diff is large: its 52 lines aren’t shown here.
This diff is large: its 8069 lines aren’t shown here.
This diff is large: its 222 lines aren’t shown here.
This diff is large: its 201 lines aren’t shown here.
This diff is large: its 76 lines aren’t shown here.
This diff is large: its 443 lines aren’t shown here.
This diff is large: its 106 lines aren’t shown here.
This diff is large: its 2541 lines aren’t shown here.
This diff is large: its 631 lines aren’t shown here.
This diff is large: its 4785 lines aren’t shown here.
This diff is large: its 101 lines aren’t shown here.
This diff is large: its 249 lines aren’t shown here.
This diff is large: its 59 lines aren’t shown here.
This diff is large: its 34324 lines aren’t shown here.
This diff is large: its 2707 lines aren’t shown here.
This diff is large: its 570 lines aren’t shown here.
This diff is large: its 88 lines aren’t shown here.
This diff is large: its 524 lines aren’t shown here.
This diff is large: its 234 lines aren’t shown here.
This diff is large: its 455 lines aren’t shown here.
This diff is large: its 90 lines aren’t shown here.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.