1292 lines · 39.0 KB · C++
RawDownload
/*----------------------------------------------------------------------------  ChucK Concurrent, On-the-fly Audio Programming Language    Compiler and Virtual Machine   Copyright (c) 2004 Ge Wang and Perry R. Cook.  All rights reserved.    http://chuck.stanford.edu/    http://chuck.cs.princeton.edu/   This program is free software; you can redistribute it and/or modify  it under the terms of the GNU General Public License as published by  the Free Software Foundation; either version 2 of the License, or  (at your option) any later version.   This program is distributed in the hope that it will be useful,  but WITHOUT ANY WARRANTY; without even the implied warranty of  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  GNU General Public License for more details.   You should have received a copy of the GNU General Public License  along with this program; if not, write to the Free Software  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  U.S.A.-----------------------------------------------------------------------------*/ //-----------------------------------------------------------------------------// file: chuck_compile.cpp// desc: chuck compile system unifying parser, type checker, and emitter//// author: Ge Wang (ge@ccrma.stanford.edu | gewang@cs.princeton.edu)// date: Autumn 2005 - original//-----------------------------------------------------------------------------#include "chuck_compile.h"#include "chuck_lang.h"#include "chuck_errmsg.h"#include "chuck_io.h"#ifndef  __DISABLE_OTF_SERVER__#include "chuck_otf.h"#endif #include "ugen_osc.h"#include "ugen_xxx.h"#include "ugen_filter.h"#include "ugen_stk.h"#include "uana_xform.h"#include "uana_extract.h" #include "ulib_ai.h"#include "ulib_doc.h"#include "ulib_machine.h"#include "ulib_math.h"#include "ulib_std.h"#include "util_string.h" #ifndef __DISABLE_NETWORK__#include "ulib_opsc.h"#endif #if defined(__PLATFORM_WIN32__)  #include "dirent_win32.h"#endif //#if defined(__WINDOWS_PTHREAD__)#include <sys/stat.h>//#endif #include <string>#include <vector>#include <algorithm>using namespace std;    // function prototypest_CKBOOL load_internal_modules( Chuck_Compiler * compiler );t_CKBOOL load_external_modules( Chuck_Compiler * compiler,                                const char * extension,                                std::list<std::string> & chugin_search_paths,                                std::list<std::string> & named_dls);t_CKBOOL load_module( Chuck_Compiler * compiler, Chuck_Env * env,                      f_ck_query query, const char * name, const char * nspc );    //-----------------------------------------------------------------------------// name: Chuck_Compiler()// desc: constructor//-----------------------------------------------------------------------------Chuck_Compiler::Chuck_Compiler(){    emitter = NULL;    code = NULL;     // REFACTOR-2017: add carrier    m_carrier = NULL;    // initialize    m_auto_depend = FALSE;     // origin hint | 1.5.0.0 (ge) added    m_originHint = te_originUnknown;}    //-----------------------------------------------------------------------------// name: ~Chuck_Compiler()// desc: destructor//-----------------------------------------------------------------------------Chuck_Compiler::~Chuck_Compiler(){    // call shutdown    this->shutdown();}    //-----------------------------------------------------------------------------// name: initialize()// desc: initialize the compiler//-----------------------------------------------------------------------------t_CKBOOL Chuck_Compiler::initialize(){    // set origin hint    m_originHint = te_originBuiltin;     // allocate the type checker    Chuck_Env * env = type_engine_init( m_carrier );    // add reference    env->add_ref();     // allocate the emitter    emitter = emit_engine_init( env );    // add reference    emitter->add_ref();    // set auto depend to 0    m_auto_depend = FALSE;     // load internal libs    if( !load_internal_modules( this ) )        goto error;     // unset origin hint    m_originHint = te_originUnknown;     return TRUE; error:    // clean up | 1.4.1.0 (ge) removed -- should be cleaned up outside    // this->shutdown();     // pop indent    EM_poplog();     return FALSE;}    //-----------------------------------------------------------------------------// name: shutdown()// desc: shutdown the compiler//-----------------------------------------------------------------------------void Chuck_Compiler::shutdown(){    // log    EM_log( CK_LOG_SYSTEM, "shutting down compiler..." ) ;    // push indent    EM_pushlog();     // TODO: free    type_engine_shutdown( env() );    // TODO: check if emitter gets cleaned up    // emit_engine_shutdown( emitter );    emitter = NULL;    code = NULL;    m_auto_depend = FALSE;    m_recent.clear();     for(std::list<Chuck_DLL *>::iterator i = m_dlls.begin();        i != m_dlls.end(); i++)    {        delete (*i);    }     m_dlls.clear();     // pop indent    EM_poplog();}     //-----------------------------------------------------------------------------// name: bind()// desc: bind a new type system module, via query function//-----------------------------------------------------------------------------t_CKBOOL Chuck_Compiler::bind( f_ck_query query_func, const std::string & name,                               const std::string & nspc ){    // log    EM_log( CK_LOG_SYSTEM, "on-demand binding compiler module '%s'...",            name.c_str() );    // push indent level    EM_pushlog();     // get env    Chuck_Env * env = this->env();    // make context    Chuck_Context * context = type_engine_make_context(        NULL, string("@[bind:") + name + string("]") );    // reset env - not needed since we just created the env    env->reset();    // load it    type_engine_load_context( env, context );     // do it    if( !load_module( this, env, query_func, name.c_str(), nspc.c_str() ) ) goto error;     // clear context    type_engine_unload_context( env );     // commit what is in the type checker at this point    env->global()->commit();     // pop indent level    EM_poplog();     return TRUE; error:     // probably dangerous: rollback    env->global()->rollback();     // clear context    type_engine_unload_context( env );     // pop indent level    EM_poplog();     return FALSE;}    //-----------------------------------------------------------------------------// name: set_auto_depend()// desc: auto dependency resolve for types//-----------------------------------------------------------------------------void Chuck_Compiler::set_auto_depend( t_CKBOOL v ){    // log    EM_log( CK_LOG_SYSTEM, "type dependency resolution: %s",            v ? "AUTO" : "MANUAL" );    m_auto_depend = v;}    //-----------------------------------------------------------------------------// name: go()// desc: parse, type-check, and emit a program//-----------------------------------------------------------------------------t_CKBOOL Chuck_Compiler::go( const string & filename,                             const string & full_path,                             const string & codeLiteral ){    t_CKBOOL ret = TRUE;    // Chuck_Context * context = NULL;     EM_reset_msg();     // check to see if resolve dependencies automatically    if( !m_auto_depend )    {        // normal (note: full_path added 1.3.0.0)        ret = this->do_normal_depend( filename, codeLiteral, full_path );    }    else // auto depend    {        // call auto-depend compile (1.4.1.0)        ret = this->do_auto_depend( filename, codeLiteral, full_path );    }     // 1.4.1.0 (ge) | added to unset the fileName reference, which determines    // how messages print to console (e.g., [file.ck]: or [chuck]:)    EM_change_file( NULL );     return ret;}    //-----------------------------------------------------------------------------// name: set_file2parse()// desc: set a FILE * for one-time use on next go(); see header for details//-----------------------------------------------------------------------------void Chuck_Compiler::set_file2parse( FILE * fd, t_CKBOOL autoClose ){    // call down to parser    ::fd2parse_set( fd, autoClose );}    //-----------------------------------------------------------------------------// name: resolve()// desc: resolve type automatically - if auto_depend is off, return FALSE//-----------------------------------------------------------------------------t_CKBOOL Chuck_Compiler::resolve( const string & type ){    t_CKBOOL ret = TRUE;     // check auto_depend    if( !m_auto_depend )        return FALSE;     // look up if name is already parsed       return ret;}    //-----------------------------------------------------------------------------// name: setReplaceDac()// desc: tell the compiler whether dac should be replaced in scripts//       with the name of an external UGen, and if so which one//-----------------------------------------------------------------------------void Chuck_Compiler::setReplaceDac( t_CKBOOL shouldReplaceDac,    const std::string & replacement ){    emitter->should_replace_dac = shouldReplaceDac;    emitter->dac_replacement = replacement;}    //-----------------------------------------------------------------------------// name: do_entire_file()// desc: parse, type-check, and emit a program//-----------------------------------------------------------------------------t_CKBOOL Chuck_Compiler::do_entire_file( Chuck_Context * context ){    // 0th-scan (pass 0)    if( !type_engine_scan0_prog( env(), g_program, te_do_all ) )         return FALSE;     // 1st-scan (pass 1)    if( !type_engine_scan1_prog( env(), g_program, te_do_all ) )        return FALSE;     // 2nd-scan (pass 2)    if( !type_engine_scan2_prog( env(), g_program, te_do_all ) )        return FALSE;     // check the program (pass 3)    if( !type_engine_check_context( env(), context, te_do_all ) )        return FALSE;     // emit (pass 4)    if( !emit_engine_emit_prog( emitter, g_program ) )        return FALSE;     // set the state of the context to done    context->progress = Chuck_Context::P_ALL_DONE;     return TRUE;}    //-----------------------------------------------------------------------------// name: do_only_classes()// desc: compile only classes definitions//-----------------------------------------------------------------------------t_CKBOOL Chuck_Compiler::do_only_classes( Chuck_Context * context ){    // 0th-scan (pass 0)    if( !type_engine_scan0_prog( env(), g_program, te_do_classes_only ) )        return FALSE;     // 1st-scan (pass 1)    if( !type_engine_scan1_prog( env(), g_program, te_do_classes_only ) )        return FALSE;     // 2nd-scan (pass 2)    if( !type_engine_scan2_prog( env(), g_program, te_do_classes_only ) )        return FALSE;     // check the program (pass 3)    if( !type_engine_check_context( env(), context, te_do_classes_only ) )        return FALSE;     // emit (pass 4)    code = emit_engine_emit_prog( emitter, g_program , te_do_classes_only );    if( !code ) return FALSE;     // set the state of the context to done    context->progress = Chuck_Context::P_ALL_DONE;     return TRUE;}    //-----------------------------------------------------------------------------// name: do_all_except_classes()// desc: compile everything except classes//-----------------------------------------------------------------------------t_CKBOOL Chuck_Compiler::do_all_except_classes( Chuck_Context * context ){    // 0th scan only deals with classes, so is not needed     // 1st-scan (pass 1)    if( !type_engine_scan1_prog( env(), g_program, te_do_no_classes ) )        return FALSE;     // 2nd-scan (pass 2)    if( !type_engine_scan2_prog( env(), g_program, te_do_no_classes ) )        return FALSE;     // check the program (pass 3)    if( !type_engine_check_context( env(), context, te_do_no_classes ) )        return FALSE;     // emit (pass 4)    code = emit_engine_emit_prog( emitter, g_program, te_do_no_classes );    if( !code ) return FALSE;     // set the state of the context to done    context->progress = Chuck_Context::P_ALL_DONE;     return TRUE;}    //-----------------------------------------------------------------------------// name: do_normal_depend()// desc: compile normally without auto-depend//-----------------------------------------------------------------------------t_CKBOOL Chuck_Compiler::do_normal_depend( const string & filename,                                           const string & codeLiteral,                                           const string & full_path ){    t_CKBOOL ret = TRUE;    Chuck_Context * context = NULL;     // expand    string theFilename = expand_filepath(filename);    string theFullpath = expand_filepath(full_path);     // parse the code    if( !chuck_parse( theFilename, codeLiteral ) )        return FALSE;     // make the context    context = type_engine_make_context( g_program, theFilename );    if( !context ) return FALSE;     // remember full path (added 1.3.0.0)    context->full_path = theFullpath;     // reset the env    env()->reset();     // load the context    if( !type_engine_load_context( env(), context ) )        return FALSE;     // 0th-scan (pass 0)    if( !type_engine_scan0_prog( env(), g_program, te_do_all ) )    { ret = FALSE; goto cleanup; }     // 1st-scan (pass 1)    if( !type_engine_scan1_prog( env(), g_program, te_do_all ) )    { ret = FALSE; goto cleanup; }     // 2nd-scan (pass 2)    if( !type_engine_scan2_prog( env(), g_program, te_do_all ) )    { ret = FALSE; goto cleanup; } 

Lines 1–500 of 1292.

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

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

Repository code

Go to file
t