Example #1
0
// if(x) then ... else ...
void TrFun_If::CompileDeclaration(
                                   PM_Automat &pm,
                                   lem::Iridium::Macro_Parser &txtfile,
                                   TrFunctions &functions,
                                   TrKnownVars &known_vars,
                                   const TrBuiltInFunSignature *signature  
                                  )
{
 src_location = pm.GetDict().GetDebugSymbols().RegisterLocation( txtfile, txtfile.tellp() );

 // ”словие опционально может быть заключено в круглые скобочки.
 const bool req_paren = txtfile.probe( B_OROUNDPAREN );
 cond = functions.CompileCall( pm, txtfile, known_vars );
 if( req_paren )
  txtfile.read_it( B_CROUNDPAREN );

 txtfile.read_it( B_THEN );
 f_then = functions.CompileCall( pm, txtfile, known_vars );
 txtfile.probe( B_SEMICOLON );

 if( txtfile.pick().GetToken()==B_ELSE )
  {
   txtfile.read_it(B_ELSE);
   f_else = functions.CompileCall( pm, txtfile, known_vars );
   txtfile.probe( B_SEMICOLON );
  }

 return;
}
Example #2
0
void TrFun_Declare::CompileDeclaration(
    PM_Automat &pm,
    lem::Iridium::Macro_Parser &txtfile,
    TrFunctions &functions,
    const TrProcedureDeclaration &procs,
    TrKnownVars &known_vars,
    const TrBuiltInFunSignature *signature
)
{
    src_location = pm.GetDict().GetDebugSymbols().RegisterLocation( txtfile, txtfile.tellp() );
    var_type.LoadTxt(pm,txtfile,functions);

    while( !txtfile.eof() )
    {
        TrFunCall *expr = NULL;
        const lem::Iridium::BethToken &vname = txtfile.read();
        if( txtfile.pick().GetToken()==B_EQUAL )
        {
            txtfile.read();
            expr = functions.CompileCall( pm, txtfile, procs, known_vars );
        }

        if( var_name.find(vname.string())!=UNKNOWN )
        {
            lem::Iridium::Print_Error( vname, txtfile );
            pm.GetIO().merr().printf( "Variable [%us] is already declared", vname.c_str() );
            throw E_ParserError();
        }

        var_name.push_back(vname);
        var_value.push_back(expr);

        known_vars.RegisterVar( var_type, vname );

        if( txtfile.pick().GetToken()!=B_COMMA )
            break;

        txtfile.read_it(B_COMMA);
    }

    txtfile.read_it(B_SEMICOLON);

    return;
}
Example #3
0
void TrFun_Lambda::CompileDeclaration(
                                      PM_Automat &pm,
                                      lem::Iridium::Macro_Parser &txtfile,
                                      TrFunctions &functions,
                                      TrKnownVars &known_vars,
                                      const TrBuiltInFunSignature *signature  
                                     )
{
 src_location = pm.GetDict().GetDebugSymbols().RegisterLocation( txtfile, txtfile.tellp() );
 ret_type = fun->ret_type;
 arg_name = fun->arg_name;
 return;
}
lem::Ptr<TrValue> TrFun_CreateWordform::Run(
                                            const ElapsedTimeConstraint & constraints,
                                            PM_Automat &pm,
                                            TrFunContext &ctx,
                                            TrTrace *trace_log
                                           ) const
{
 const int mark = TrTraceActor::seq++;
 if( trace_log!=NULL )
  trace_log->Enter( new TrTraceFunCall(mark,src_location,this,&ctx,false) );

 SynGram &sg = pm.GetDict().GetSynGram();
 const int ekey = ientry->Run(constraints,pm,ctx,trace_log)->GetInt();
 const SG_Entry &e = sg.GetEntry( ekey );

 Word_Form *wf = new Word_Form( form_name.empty() ? e.GetName() : form_name, e.GetKey() );

 // Скопируем в словоформу атрибуты статьи
 for( lem::Container::size_type i=0; i<e.attrs().size(); ++i )
  {
   wf->SetState( e.attrs()[i] ); 
  }

 {
 // Теперь зададим измерения, которые определены внутри {...}
 for( lem::Container::size_type i=0; i<coords.size(); ++i )
  {
   const int icoord = coords[i]->Run(constraints,pm,ctx,trace_log)->GetInt();
   const int istate = states[i]->Run(constraints,pm,ctx,trace_log)->GetInt();

   wf->SetState( GramCoordPair( icoord, istate ) ); 
  }
 }

 if( form_name.empty() )
  {
   wf->Rename_By_States(sg);
  }

 Tree_Node *tn = new Tree_Node(wf,true);
 lem::Ptr<TrValue> ret( new TrValue(tn,true) ); 

 if( trace_log!=NULL )
  trace_log->Leave( new TrTraceFunCall(mark,src_location,this,&ctx,false) );

 return ret;
}
Example #5
0
void TrType::LoadTxt(
    PM_Automat &pm,
    lem::Iridium::Macro_Parser &txtfile,
    const TrFunctions &funs
)
{
    is_const = txtfile.probe( L"const" );

    const lem::Iridium::BethToken& t = txtfile.read();

    if( t.string().eqi( L"bool" ) )
        type = Bool;
    else if( t.string().eqi( L"int" ) )
        type = Int;
    else if( t.string().eqi( L"string" ) )
        type = String;
    else if( t.string().eqi( L"tree" ) )
        type = Tree;
    else if( t.string().eqi( L"trees" ) )
        type = Trees;
    else if( t.string().eqi( L"fun" ) )
        type = Fun;
    else if( t.string().eqi( L"void" ) )
        type = Void;
    else if( t.string().eqi( L"variant" ) )
        type = Variant;
    else if( t.string().eqi( L"tuple" ) )
        type = Tuple;
    else
    {
        lem::Iridium::Print_Error( t, txtfile );
        pm.GetIO().merr().printf( "Unknown type [%us]\n", t.string().c_str() );
        throw E_ParserError();
    }

    return;
}
Example #6
0
void TrFunction::CompileDeclaration(
                                    PM_Automat &pm,
                                    lem::Iridium::Macro_Parser &txtfile,
                                    TrFunctions &functions,
                                    const TrProcedureDeclaration &procs,
                                    const TrKnownVars *lambda_caller
                                   )
{
 const bool is_lambda = lambda_caller!=NULL;

 lem::Iridium::BSourceState fun_beg = txtfile.tellp();

 ret_type.LoadTxt( pm, txtfile, functions );

 lem::Iridium::BSourceState ss = txtfile.tellp();

 try
  {
   if( is_lambda )
    {
     // Формируем "невозможное" имя лямбда-функции, которое наверняка не будет
     // пересекаться с пользовательскими и встроенными функциями.
     static int lambda_number=0;
     name = L" $lambda";
     name += to_ustr(lambda_number++);
    }
   else
    {
     name = txtfile.read();
    }

   if( pm.GetDict().GetDebugLevel_ir()>=3 )
    {
     // Печатаем имя транслируемой статьи для контроля за процессом
     // парсинга Словаря.
     pm.GetDict().GetIO().mecho().printf( "function [%vfA%us%vn]->", name.c_str() );
    }

   if( !is_lambda && !CorrectName(name) )
    {
     lem::Iridium::Print_Error( ss, txtfile );
     pm.GetIO().merr().printf( "Invalid function name [%us]\n", name.c_str() );
     throw E_ParserError();
    }

   txtfile.read_it( B_OROUNDPAREN );

   TrKnownVars call_vars( lambda_caller==NULL ? &functions.global_known_vars : lambda_caller );

   // Список формальных аргументов
   while( !txtfile.eof() )
    {
     if( txtfile.pick().GetToken()==B_CROUNDPAREN )
      break;

     if( arg_name.size()>0 )
      txtfile.read_it(B_COMMA);

     TrType at;
     at.LoadTxt(pm,txtfile,functions);

     const lem::Iridium::BethToken &an = txtfile.read();

     if( arg_name.find(an)!=UNKNOWN )
      {
       lem::Iridium::Print_Error( an, txtfile );
       pm.GetIO().merr().printf( "Function [%us] call argument [%us] is already declared\n", name.c_str(), an.string().c_str() );
       throw E_ParserError();
      }
  
     arg_type.push_back(at);
     arg_name.push_back(an.string());

     call_vars.RegisterVar( at, an.string() );
    }

   txtfile.read_it( B_CROUNDPAREN );

   if( txtfile.pick().GetToken()==B_SEMICOLON )
    {
     txtfile.read();
     // Это форвардное объявление функции, без определения тела.
    }
   else
    {
     // Чтобы компилировать рекурсивные функции, мы сейчас добавим в список функций свое форвардное объявление.
     if( !is_lambda && !functions.IsFunction(name) )
      {
       TrFunction *forward = MakeForwardDeclaration();
       functions.AddForwardDeclaration(forward);
      }    

     // В фигурных скобочках - тело функции. Оно компилируется как вызов специальной функции-группы {}
     txtfile.read_it( B_OFIGPAREN );
     txtfile.backward();
     body = functions.CompileCall( pm, txtfile, procs, call_vars );
    }

   if( pm.GetDict().GetDebugLevel_ir()>=3 )
    pm.GetIO().mecho().printf( "%vfAOK%vn\n" );
  }
 catch(...)
  {
   lem::Iridium::Print_Error( ss, txtfile );
   pm.GetIO().merr().printf( "Error in function [%us] definition\n", name.c_str() );
   throw;
  }

 return;
}
void TrFun_CreateWordform::CompileDeclaration(
                                              PM_Automat &pm,
                                              lem::Iridium::Macro_Parser &txtfile,
                                              TrFunctions &functions,
                                              const TrProcedureDeclaration &procs,
                                              TrKnownVars &known_vars,
                                              const TrBuiltInFunSignature *signature  
                                             )
{
 lem::Iridium::BSourceState ebeg = txtfile.tellp();

 SynGram &sg = pm.GetDict().GetSynGram();

 const lem::Iridium::BethToken &class_name = txtfile.read();
 const int iclass = sg.FindClass(class_name);

 txtfile.read_it( B_COLON );
 lem::Iridium::BSourceState ename = txtfile.tellp();

 UCString entry_name = sol_read_multyname( pm.GetIO(), txtfile, B_OFIGPAREN );
     
 const int v_ientry = sg.FindEntry( entry_name, iclass, false );
 if( v_ientry==UNKNOWN )
  {
   lem::Iridium::Print_Error( ename, txtfile );
   pm.GetIO().merr().printf( "Unknown entry [%vfE%us:%us%vn]\n", class_name.c_str(), entry_name.c_str() );
   throw E_ParserError();
  } 

 ientry = new TrFun_Constant( TrIntValue(sg.GetEntry(v_ientry).GetKey()) );

 while( !txtfile.eof() )
  {
   if( txtfile.pick().GetToken()==B_CFIGPAREN )
    {
     break;
    }

   // Координатная пара или имя формы слова в апострофах

   lem::Iridium::BethToken cn = txtfile.read();
   if( lem::in_quotes(cn.string()) )
    {
     form_name = strip_quotes(cn.string());
    }
   else
    {
     bool AFFIRM=true;

     if( cn.GetToken()==B_NEGATIVE )
      {
       // Оператор отрицания перед определением координаты!
       AFFIRM=false;
       cn = txtfile.read();
      }

     // Для бистабильных - просто имя координаты.
     int icoord=UNKNOWN, istate=UNKNOWN;

     icoord = sg.FindCoord(cn).GetIndex();
     if( icoord==UNKNOWN )
      {
       lem::Iridium::Print_Error( cn, txtfile );
       pm.GetIO().merr().printf( "Unknown coordinate [%vfE%us%vn]\n", cn.c_str() );
       throw E_ParserError();
      }

     if( sg.coords()[icoord].IsBistable() )
      {
       istate=AFFIRM ? 1 : 0;
      }
     else
      {
       txtfile.read_it( B_COLON );
       const lem::Iridium::BethToken & sn = txtfile.read();
       istate = sg.coords()[icoord].FindState(sn);

       if( istate==UNKNOWN )
        {
         // Нет такого состояния для этого измерения.
         lem::Iridium::Print_Error(sn,txtfile);
          sg.GetIO().merr().printf(
                                    "State [%vfE%us%vn] is not declared for coordinate [%vfE%us%vn]\n"
                                    , sn.c_str(), cn.c_str()
                                   );
         throw E_ParserError();
        }
      }

     TrIntValue v2( icoord );
     coords.push_back( new TrFun_Constant(v2) );
  
     TrIntValue v3( istate );
     states.push_back( new TrFun_Constant(v3) );
    }
  }

 txtfile.read_it( B_CFIGPAREN );

 return;
}