source: tol/tol/btol/bgrammar/graacc.cpp @ 47c5d6f

1941-docker-image-to-testdevel
Last change on this file since 47c5d6f was 47c5d6f, checked in by Víctor de Buen <vdebuen@…>, 17 years ago

Class instances doesn't store the Class methods that will be stored as just one copy in the Class handler.
Fixed #722

git-svn-id: ​https://www.tol-project.org/svn/tolp/trunk@1229 be4846ae-f051-483a-831f-b64e7d08527f

  • Property mode set to 100644
File size: 30.2 KB
Line 
1/* graacc.cpp: Global variables and access functions of BGrammar
2               GNU/TOL Language.
3
4   Copyright (C) 2003-2005 - Bayes Decision, SL (Spain [EU])
5
6   This program is free software; you can redistribute it and/or modify
7   it under the terms of the GNU General Public License as published by
8   the Free Software Foundation; either version 2, or (at your option)
9   any later version.
10
11   This program is distributed in the hope that it will be useful,
12   but WITHOUT ANY WARRANTY; without even the implied warranty of
13   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14   GNU General Public License for more details.
15
16   You should have received a copy of the GNU General Public License
17   along with this program; if not, write to the Free Software
18   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
19   USA.
20 */
21
22#if defined(_MSC_VER)
23#include <win_tolinc.h>
24#endif
25
26#include <tol/tol_bgrammar.h>
27#include <tol/tol_boper.h>
28#include <tol/tol_bout.h>
29#include <tol/tol_barray.h>
30#include <tol/tol_bcodgra.h>
31#include <tol/tol_bsetgra.h>
32#include <tol/tol_bdir.h>
33#include <tol/tol_blanguag.h>
34#include <tol/tol_bsymboltable.h>
35#include <tol/tol_bspfun.h>
36#include <tol/tol_bsymboltable.h>
37#include <tol/tol_bnameblock.h>
38#include <tol/tol_bstruct.h>
39
40//--------------------------------------------------------------------
41// INICIALIZATION
42//   Global variables (static in the class BGrammar).
43//--------------------------------------------------------------------
44BTraceInit("graacc.cpp");
45
46//--------------------------------------------------------------------
47BGrammar* BGrammar::Grammar() const
48//--------------------------------------------------------------------
49{
50    return((BGrammar*)this);
51}
52
53
54//--------------------------------------------------------------------
55void BGrammar::DelObject(BSyntaxObject* var)
56//--------------------------------------------------------------------
57{
58  if(var)
59  {
60    if(var->IsHashed())
61    {
62      symbolTable_->Kill(var);
63    } /*
64    else if(var->HasName() || var->LocalName().HasName())
65    {
66      BStackManager::Pop(obj);
67    }*/
68  }
69}
70
71//--------------------------------------------------------------------
72//! If the variable has name then adds it to hash table if
73//! is global or else to stack. Any way puts current level
74//! to object
75void BGrammar::AddObject(BSyntaxObject* obj)
76//--------------------------------------------------------------------
77{
78  if(obj)
79  {
80    if(Level())
81    {
82      if(obj->HasName() || obj->LocalName().HasName())
83      {
84        BStackManager::Push(obj);
85      }
86    }
87    else if(obj->HasName() && !obj->IsHashed())
88    {
89      int add = symbolTable_->Add(obj);
90      if(add>=0) { obj->PutHashed(true); }
91    }
92    obj->PutLevel(Level());
93  }
94}
95
96//- DYNAMIC SCOPE --------------
97#ifdef __USE_DYNSCOPE__
98
99//--------------------------------------------------------------------
100BSyntaxObject* BGrammar::FindLocal(const BText& name)
101
102/*! Looks for a BSyntaxObject atom in the list with LocalName() equal
103 *  than name.
104 *  If the BSyntaxObject is not in the list, returns NIL.
105*/
106//--------------------------------------------------------------------
107{
108  BSyntaxObject* obj = BStackManager::Find(name);
109  return(obj);
110}
111#endif /* ifdef __USE_DYNSCOPE__ */
112//------------------------------
113
114//- LEXICAL SCOPE --------------
115#ifndef __USE_DYNSCOPE__
116
117//--------------------------------------------------------------------
118BSyntaxObject* BGrammar::FindLocal(const BText& name)
119
120/*! Looks for a BSyntaxObject atom in the list with LocalName() equal
121 *  than name.
122 *  If the BSyntaxObject is not in the list, returns NIL.
123*/
124//--------------------------------------------------------------------
125{
126  BList* lst = stack_;
127  BSyntaxObject* found = NIL;
128  if(!lst || !name.HasName()) { return(NIL); }
129  assert(!stack_level.empty());
130  found = BNameBlock::LocalMember(name);
131  if(found) { return(found); }
132
133  //std::cout << stack_level;
134  level_list_t::iterator level_iter;
135  BInt current_size, fun_level;
136
137  level_iter = stack_level.begin();
138  fun_level = level_iter->level;
139  current_size = BGrammar::StackSize();
140
141
142    do {
143      while(lst && !found && current_size > level_iter->size)
144      {
145  BSyntaxObject* obj = (BSyntaxObject*)Car(lst);
146  if(obj)
147  {
148          if(obj->LocalName().HasName())
149          {
150            if(obj->LocalName()==name)
151            {
152              found = obj;
153            }
154          }
155          else
156          {
157            if(obj->Name()==name)
158            {
159              found = obj;
160            }
161          }
162  }
163  lst = Cdr(lst);
164        --current_size;
165      }
166      if (found) break;
167      /* not found in fun_level, now look one level "down" */
168      --fun_level;
169      if (fun_level > 0) {
170        for (++level_iter;
171             level_iter != stack_level.end() && level_iter->level != fun_level;
172             ++level_iter) {
173          //std::cout << "skipping " << *level_iter;
174          /* skip this range of objects */
175          while (lst && current_size > level_iter->size) {
176            lst = Cdr(lst);
177            --current_size;
178          }
179        }
180        //fun_level = level_iter->level;
181        /* precondition */
182        assert(level_iter != stack_level.end());
183      }
184    } while (fun_level > 0);
185    return(found);
186}
187#endif /* ifndef __USE_DYNSCOPE__ */
188//------------------------------
189
190
191//--------------------------------------------------------------------
192BSyntaxObject* BGrammar::New(const BText& name,
193                             BSyntaxObject* syn) const
194//--------------------------------------------------------------------
195{
196  BSyntaxObject* obj = NIL;
197  if(newRenamed_)
198  {
199    obj=(*newRenamed_)(name, syn);
200  }
201  return(obj);
202}
203
204//--------------------------------------------------------------------
205BSyntaxObject* BGrammar::NewFunArg(const BText& localName,
206                                   BSyntaxObject* syn) const
207//--------------------------------------------------------------------
208{
209  BSyntaxObject* obj = NIL;
210  if(newFunArg_)
211  {
212    obj=(*newFunArg_)(localName, syn);
213  }
214  return(obj);
215}
216
217
218//--------------------------------------------------------------------
219BGrammar* BGrammar::Last()
220
221/*! Returns the last used grammar.
222 */
223//--------------------------------------------------------------------
224{
225    if(!last_) { last_=GraAnything(); }
226    return(last_);
227}
228
229
230//--------------------------------------------------------------------
231BGrammar* BGrammar::FindByName(const BText& name, bool sendError)
232
233/*! Finds a grammar with name \a name. If it doesn't exist prints an
234 *  error message and returns NIL.
235 * \param name Name of grammar to find
236 */
237//--------------------------------------------------------------------
238{
239  BGrammar* grammar = NULL;
240  BGraHashByName::const_iterator found = graByName_.find(name);
241  if(found!=graByName_.end())
242  {
243    grammar = found->second;
244  }
245  if(!grammar && sendError)
246  { Error(Out()+name+I2(" is not a grammar."," no es una gramática.")); }
247  return(grammar);
248}
249
250//--------------------------------------------------------------------
251BGrammar* BGrammar::FindByGid(BGrammarId gid, bool sendError)
252
253/*! Finds a grammar with gid_ == gid. If it doesn't exist prints an
254 *  error message and returns NIL.
255 * \param gif Grammar identifier of grammar to find
256 */
257//--------------------------------------------------------------------
258{
259  BGrammar* grammar = NULL;
260  BGraHashByGid::const_iterator found = graByGid_.find(gid);
261  if(found!=graByGid_.end())
262  {
263    grammar = found->second;
264  }
265  if(!grammar && sendError)
266  {
267    Error(Out()+"[FATAL] "+(int)gid+
268          I2(" is not a grammar identifier. TOL cannot continue.",
269             " no es un identificador de gramática. TOL no puede continuar."));
270    abort();
271  }
272  return(grammar);
273}
274
275//--------------------------------------------------------------------
276BMethod* BGrammar::FindMethod(const BText& name, bool sendError) const
277
278/*! Looks for a valid method with name \a name for this grammar. If
279 *  it doesn't exist prints an error message and returns NIL.
280 * \param name Name of method to find
281 */
282//--------------------------------------------------------------------
283{
284  BMethod* found = NULL;
285  BObjectCRef aux(name);
286  int f = sortedMethods_.FindSorted(&aux,AtmCmp);
287  if(f>=0)
288  {
289    found = (BMethod*)sortedMethods_[f];
290  }
291  if(!found && (this!=GraAnything()))
292  {
293    found = GraAnything()->FindMethod(name,false);
294  }
295  if(!found && sendError)
296  { Error(Out()+name + I2(" is not a " + Name() + " method.",
297          " No es un método de " + Name())); }
298    return(found);
299}
300
301
302//--------------------------------------------------------------------
303BGrammar* BGrammar::AddCasting(BGrammar* gra)
304
305/*! Adds a casting to list of valid operators for this grammar and
306 *  returns it.
307 */
308//--------------------------------------------------------------------
309{
310  assert(gra && !hasCasting_[gra->Gid()]);
311  castings_.Add(gra);
312  hasCasting_[gra->Gid()] = true;
313  return (gra);
314}
315
316
317//--------------------------------------------------------------------
318void   BGrammar::AddMethod(BMethod* met)
319
320/*! Adds a method to list of valid methods for this grammar and
321 *  returns it.
322 */
323//--------------------------------------------------------------------
324{
325//Std(BText("\nAdding method ")+met->Name()+" to grammar "+Name()+" ... ");
326  if(met && !FindMethod(met->Name(),false))
327  {
328  methods_ = Cons((BCore*)met, methods_);
329    sortedMethods_.AddSorted(met,AtmCmp);
330  }
331}
332
333
334//--------------------------------------------------------------------
335BSyntaxObject* BGrammar::FindConstant(const BText& name)const
336{
337    BSyntaxObject* obj = NIL;
338    if(findConstant_) { obj=(*findConstant_)(name); }
339    return(obj);
340}
341
342
343//--------------------------------------------------------------------
344BSyntaxObject* BGrammar::FindVariable(const BText& name) const
345{
346  BObjClassify oc(this,BOBJECTMODE);
347  BSyntaxObject* result = symbolTable_->Search(oc, name);
348  if(result) { return(result); }
349  result = BNameBlock::UsingMember(name);
350  if( result &&
351     (result->Mode()==BOBJECTMODE)&&
352     (result->Grammar()==this))
353  {
354    return(result);
355  }
356  else
357  {
358    return(NULL);
359  }
360}
361
362//--------------------------------------------------------------------
363BSyntaxObject* BGrammar::UnknownVar() const
364{
365         if(this==GraCode    ()) return GraCode    ()->FindVariable("UnknownCode");
366    else if(this==GraComplex ()) return GraComplex ()->FindVariable("?");
367    else if(this==GraDate    ()) return GraDate    ()->FindVariable("UnknownDate");
368    else if(this==GraMatrix  ()) return GraMatrix  ()->FindVariable("UnknownMatrix");
369    else if(this==GraPolyn   ()) return GraPolyn   ()->FindVariable("UnknownPolyn");
370    else if(this==GraRatio   ()) return GraRatio   ()->FindVariable("UnknownRatio");
371    else if(this==GraReal    ()) return GraReal    ()->FindVariable("?");
372    else if(this==GraSerie   ()) return GraSerie   ()->FindVariable("UnknownSerie");
373    else if(this==GraSet     ()) return GraSet     ()->FindVariable("EMPTY");
374    else if(this==GraText    ()) return GraText    ()->FindVariable("NULL");
375    else if(this==GraTimeSet ()) return GraTimeSet ()->FindVariable("W");
376#ifdef __USE_TC__
377    else if(this==GraCTime   ()) return GraCTime   ()->FindVariable("UnknownCTime");
378    else if(this==GraCTimeSet()) return GraCTimeSet()->FindVariable("CTEmpty");
379    else if(this==GraCSeries ()) return GraCSeries ()->FindVariable("UnknownCSeries");
380#endif
381    else return 0;
382}
383
384//--------------------------------------------------------------------
385BOperator* BGrammar::FindFunction(const BText& name) const
386{
387  BObjClassify oc(this,BBUILTINFUNMODE);
388  return((BOperator*)(symbolTable_->Search(oc, name)));
389}
390
391//--------------------------------------------------------------------
392BSyntaxObject* BGrammar::FindUserFunc(const BText& name) const
393{
394  BObjClassify oc(this,BUSERFUNMODE);
395  BSyntaxObject* result = symbolTable_->Search(oc, name);
396  if(result) { return(result); }
397  result = BNameBlock::UsingMember(name);
398  if( result &&
399     (result->Mode()==BUSERFUNMODE)&&
400     (result->Grammar()==this))
401  {
402    return(result);
403  }
404  else
405  {
406    return(NULL);
407  }
408}
409
410//--------------------------------------------------------------------
411  static BSyntaxObject* getOperand(const BGrammar* gra, BSyntaxObject* obj)
412//--------------------------------------------------------------------
413{
414  BSyntaxObject* found =obj;
415  if(obj)
416  {
417    BGrammar* g = obj->Grammar();
418    int m = obj->Mode();
419    if((m!=BOBJECTMODE) || ((gra!=GraAnything()) && (g!=gra) && !gra->HasCasting(g)))
420    {
421      found =  NULL;
422    }
423  }
424  return(found);
425}
426
427//--------------------------------------------------------------------
428  static BOperator* getOperator(const BGrammar* gra, BSyntaxObject* obj)
429//--------------------------------------------------------------------
430{
431  BOperator* found = NULL;
432  if(obj)
433  {
434    int m = obj->Mode();
435    BGrammar* g = obj->Grammar();
436    if(m==BSTRUCTMODE)
437    {
438      BStruct* str = (BStruct*)obj;
439      found = str->Function();
440      g = GraSet();
441    }
442    else if((m==BUSERFUNMODE)||(m==BBUILTINFUNMODE))
443    {
444      found = (BOperator*)obj;
445    }
446    else if((m==BOBJECTMODE)&&(g==GraCode()))
447    {
448      found = Code(obj).Operator();
449      if(found) { g = found->Grammar(); }
450    }
451    if(found &&
452       (g!=gra) &&
453       (gra!=GraAnything()) &&
454       (g!=GraAnything()) &&
455       !gra->HasCasting(g))
456    {
457      found = NULL;
458    }
459  }
460  return(found);
461}
462
463//--------------------------------------------------------------------
464BSyntaxObject* BGrammar::FindOperand(const BText& name,
465                                     bool mayBeConst) const
466
467/*! If name is a valid constant for this grammar returns it.
468 *  Else if exist a valid operand for this grammar in stack_ with
469 *  name \a name returns it.
470 *  Else if exist a operand in the list of instances of this grammar
471 *  with name \a name returns it.
472 *  Else if has a data base finder try to find it using this finder.
473 *  Else prints a error message and returns NIL.
474 *  The argument stack_ is the local list of instances for a
475 *  evaluable object. Those instances are only available for the
476 *  following instances of stack_.
477 */
478//--------------------------------------------------------------------
479{
480//Std(BText("\nFindOperand ") + name +" in "+Name()+
481//      "\nStack = "+LstIdentify(stack_));
482//InitTotalTime("BGrammar::FindOperand");
483  int i;
484  if(!name.HasName()) { return(NIL); }
485  BSyntaxObject* found =NIL;
486  BObjByClassHash* obch;
487  BObjByClassHash::const_iterator f;
488  const BText& graName=Name();
489  BOperator* opr = NULL;
490  if(mayBeConst)
491  {
492    found = FindConstant(name);
493    found = getOperand(this, found);
494  }
495/* */
496  const BClass* cls = BClass::currentClassBuildingInstance_;
497  if(!found && cls && (this==GraCode()))
498  {
499    BSyntaxObject* met = cls->FindMethod(name);
500    if(met)
501    {
502      if(met->Mode()==BUSERFUNMODE)
503      {
504        opr = (BOperator*)met;
505        found = opr->GetCode();
506      }
507      else if(met->Mode()==BOBJECTMODE)
508      {
509        found = met;
510      }
511    }
512  }
513/* */
514  if(!found)
515  {
516    found = BNameBlock::LocalMember(name);
517    found = getOperand(this, found);
518  }
519  if(!found)
520  {
521    found = FindLocal(name);
522    found = getOperand(this, found);
523  }
524  if(!found)
525  {
526    if(this!=GraCode())
527    {
528      if(dbiFinder_) { found = (*dbiFinder_)(graName, name); }
529      BObjClassify oc(this,BOBJECTMODE);
530      if(!found) { found = symbolTable_->Search(oc, name); }
531      if(!found && (obch = symbolTable_->Search(name)) && obch->size())
532      {
533        f = obch->find(oc);
534        if(f!=obch->end()) { found = f->second; }
535        for(int i=0; !found && (i<castings_.Size()); i++)
536        {
537          BObjClassify oci(castings_[i], BOBJECTMODE);
538          f = obch->find(oci);
539          if(f!=obch->end()) { found = f->second; }
540        }
541      }
542    }
543    else if((obch = symbolTable_->Search(name)) && obch->size())
544    {
545      BArray<BOperator*> options;
546      opr=NULL;
547      for(f=obch->begin(); f!=obch->end(); f++)
548      {
549        const BGrammar* g = f->first.grammar_;
550        int             m = f->first.mode_;
551        if(!found)
552        {
553          if(m==BUSERFUNMODE)
554          {
555            opr = (BOperator*)f->second;
556            found = opr->GetCode();
557          }
558          else if((m==BOBJECTMODE)&&(g==GraCode()))
559          {
560            found = f->second;
561            opr = Code(found).Operator();
562          }
563        }
564        else if(m==BUSERFUNMODE)
565        {
566          if(BSymbolTable::AreCompatible(opr,f->second))
567          {
568            options.Add((BOperator*)f->second);
569          }
570        }
571        else if((m==BOBJECTMODE)&&(g==GraCode()))
572        {
573          if(BSymbolTable::AreCompatible(found,f->second))
574          {
575            options.Add(Code(f->second).Operator());
576          }
577        }
578      }
579      if(opr && options.Size())
580      {
581        BText another = "";
582        for(i=0; i<options.Size(); i++)
583        {
584          another << BText("  ")+options[i]->LexInfo()+";\n";
585          if(opr->Grammar()->Precedence()>options[i]->Grammar()->Precedence())
586          {
587            opr = options[i];
588          }
589        }
590        Warning(I2("Function symbol ", "El símbolo de función ")+name+
591                I2(" is ambiguous.",   " es ambiguo.")+"\n"+
592                opr->LexInfo()+"\n"+
593                I2(" has been selected but there were these others ",
594                   " ha sido elegido pero había estas otras ")+options.Size()+
595                I2(" options"," opciones")+":\n"+another);
596      }
597     
598    }
599  }
600  if(!found)
601  {
602    found = BNameBlock::UsingMember(name);
603    found = getOperand(this, found);
604  }
605//SumPartialTime;
606  return(found);
607}
608
609
610//--------------------------------------------------------------------
611BOperator* BGrammar::FindOperator(const BText& name)const
612
613/*! Looks for a valid operator with name name for this grammar. If it
614 *  doesn't exist prints an error message and returns NIL.
615 */
616//--------------------------------------------------------------------
617{
618//InitTotalTime("BGrammar::FindOperator");
619//Std(BText("\nFinding Operator ") + name +" in "+Name());
620//Std(Out()+"\nWith Stack = \n"+LstText(stack_,"{","}","\n"));
621  BOperator* found = NULL;
622/* */
623  const BClass* cls = BClass::currentClassBuildingInstance_;
624  if(cls)
625  {
626    BSyntaxObject* met = cls->FindMethod(name);
627    if(met)
628    {
629      if(met->Mode()==BUSERFUNMODE)
630      {
631        found = (BOperator*)met;
632      }
633      else if(met->Mode()==BOBJECTMODE)
634      {
635        BUserCode* uCode = UCode(met);
636        found = uCode->Contens().Operator();
637      }
638    }
639  }
640/* */
641  if(!found)
642  {
643    found = getOperator(this, BNameBlock::LocalMember(name));
644  }
645  if(!found)
646  {
647    found = getOperator(this, FindLocal(name));
648  }
649  BGrammar* g;
650  BObjByClassHash* obch=NULL;
651  BObjByClassHash::const_iterator f;
652
653  if(!found)
654  {
655    BObjClassify oc(this, BUSERFUNMODE);
656    found = (BOperator*)symbolTable_->Search(oc, name);
657    if(!found && (obch = symbolTable_->Search(name)) && obch->size())
658    {
659      f = obch->find(oc);
660      if(f!=obch->end()) { found = (BOperator*)f->second; }
661      for(int i=0; !found && (i<castings_.Size()); i++)
662      {
663        BObjClassify oci(castings_[i], BUSERFUNMODE);
664        f = obch->find(oci);
665        if(f!=obch->end()) { found = (BOperator*)f->second; }
666      }
667      if(!found)
668      {
669        BObjClassify ock(GraCode(), BOBJECTMODE);
670        f = obch->find(ock);
671        if(f!=obch->end())
672        {
673          BUserCode* uCode = UCode(f->second);
674          BOperator* opr = uCode->Contens().Operator();
675          if(!opr)
676          {
677            Error(I2("Corrupted Code object ",
678                     "Objeto Code corrupto ")+uCode->Identify());
679          }
680          else
681          {
682            g = opr->Grammar();
683            if((g==GraAnything()) || (g==this) || HasCasting(g)) { found=opr; }
684          }
685        }
686      }
687    }
688  }
689  if(!found)
690  {
691    found = getOperator(this, BNameBlock::UsingMember(name));
692  }
693//if(found) { Std(Out()+"\nFound Operator : \n"+found->Dump()); }
694//SumPartialTime;
695  return(found);
696}
697
698
699//--------------------------------------------------------------------
700BList* BGrammar::Methods() const
701
702/*! Returns the list of valid methods for the grammar
703 */
704//--------------------------------------------------------------------
705{
706  return(methods_);
707}
708
709
710//--------------------------------------------------------------------
711BList* BGrammar::Operators() const
712
713/*! Returns a copy of the list of valid operators for the grammar
714 */
715//--------------------------------------------------------------------
716{
717  BList* opr;
718  BObjClassify oc(this, BUSERFUNMODE);
719  opr = symbolTable_->Select(NIL, oc);
720  opr = BNameBlock::Select(opr, oc);
721  return(opr);
722}
723
724
725//--------------------------------------------------------------------
726BList*  BGrammar::Variables() const
727
728/*! Returns a copy of the list of valid variables for this grammar.
729 */
730//--------------------------------------------------------------------
731{
732  BObjClassify oc(this,BOBJECTMODE);
733  BList* var = symbolTable_->Select(NIL,oc);
734  var = BNameBlock::Select(var, oc);
735  return(var);
736}
737
738
739//--------------------------------------------------------------------
740BList* BGrammar::GetMethods() const
741
742/*! Returns the list of valid methods for the grammar
743*/
744//--------------------------------------------------------------------
745{
746  return(LstDuplicate(Methods()));
747}
748
749
750//--------------------------------------------------------------------
751BList* BGrammar::GetOperators() const
752
753/*! Returns a copy of the list of valid operators for the grammar
754 */
755//--------------------------------------------------------------------
756{
757//Std(BText("\n")+Name()+"::GetOperators()");
758  BObjClassify oc(this, BUSERFUNMODE);
759  BList* lst_opr = symbolTable_->Select(NIL, oc);
760  BObjClassify nboc(GraNameBlock(), BOBJECTMODE);
761  BList* lst_unb = symbolTable_->Select(NIL,nboc);
762  BUserNameBlock* unb = NULL;
763  BList* aux = lst_unb;
764//Std(BText("\n")+Name()+"::GetOperators() global "+LstLength(lst_opr));
765  while(lst_unb)
766  {
767    unb = (BUserNameBlock*)lst_unb->Car();
768  //Std(BText("\n")+Name()+"::GetOperators() Exploring NameBlock "+unb->FullName());
769    lst_opr = unb->Contens().SelectMembersDeep(lst_opr, oc);
770    lst_unb = lst_unb->Cdr();
771  }
772  DESTROY(aux);
773/* * /
774  Std(BText("\n")+Name()+"::GetOperators() all "+LstLength(lst_opr));
775  aux = lst_opr;
776  while(aux)
777  {
778    BSyntaxObject* obj = (BSyntaxObject*)aux->Car();
779    Std(BText("\n  ")+obj->Grammar()->Name()+" "+obj->FullName());
780    aux = aux->Cdr();
781  }
782/* */
783  return(lst_opr);
784}
785
786//--------------------------------------------------------------------
787BList*  BGrammar::GetVariables() const
788
789/*! Returns a copy of the list of valid variables for this grammar.
790 */
791//--------------------------------------------------------------------
792{
793    return(Variables());
794}
795
796
797//--------------------------------------------------------------------
798BList* GraList(const BText& textList)
799
800/*! Returns a new list with the grammars which name is in textList.
801 */
802//--------------------------------------------------------------------
803{
804    BInt error = BFALSE;
805    BList* lst=NIL;
806    BArray<BText> name;
807    ReadAllTokens(textList, name, ' ');
808    for(BInt n=name.Size()-1; n>=0; n--)
809    {
810  BGrammar* gra = BGrammar::FindByName(name[n]);
811  if(!gra) { error= BTRUE; }
812  else     { lst = Cons(gra, lst); }
813    }
814    if(error) { lst = LstDestroyAllCons(lst); }
815    return(lst);
816}
817
818
819//--------------------------------------------------------------------
820void BGrammar::PutLast(BGrammar* gra)
821
822/*! Puts the last_ = grammarName.
823 */
824//--------------------------------------------------------------------
825{
826  last_=gra;
827}
828
829
830//--------------------------------------------------------------------
831BDat BGrammar::Compare(BSyntaxObject* syn1, BSyntaxObject* syn2) const
832//--------------------------------------------------------------------
833{
834  assert(syn1 && syn2);
835  syn1->Do();
836  syn2->Do();
837  BDat compare;
838  if(compare_ && (*compare_) &&
839     (this==syn2->Grammar()) && (this==syn1->Grammar()))
840  {
841    compare = (*compare_)(syn1, syn2);
842  }
843  return(compare);
844}
845
846//--------------------------------------------------------------------
847/*! Invokes \a castingFunction_ in order to convert BSyntaxObject
848 * \a obj given as argument into an object of (this) Grammar.
849 * \return a valid object whether a conversion has been done, null
850 *         in other case.
851 */
852BSyntaxObject* BGrammar::Casting(BSyntaxObject* obj)
853//--------------------------------------------------------------------
854{
855  BSyntaxObject* cast = (*castingFunction_)(obj);
856  return cast;
857}
858
859
860//--------------------------------------------------------------------
861BSyntaxObject* BAnyGrammar::FindOperand(const BText& name, bool mayBeConst) const
862
863/*! Finds an object named name in any grammar.
864 */
865//--------------------------------------------------------------------
866{
867  int i;
868  BSyntaxObject* found = NULL;
869  if(mayBeConst)
870  {
871    if(!found) { found = GraText()->FindConstant(name); }
872    if(!found) { found = GraDate()->FindConstant(name); }
873    if(!found) { found = GraReal()->FindConstant(name); }
874  }
875  if(!found) { found = getOperand(this, BNameBlock::LocalMember(name)); }
876  if(!found) { found = getOperand(this, FindLocal(name)); }
877  BObjByClassHash* obch;
878  BObjByClassHash::const_iterator f;
879  if(!found && (obch = symbolTable_->Search(name)) && obch->size())
880  {
881    BObjClassify oc(last_, BOBJECTMODE);
882    f = obch->find(oc);
883    if(f!=obch->end()) { found = f->second; }
884    for(i=0; !found && (i<last_->GetCastings().Size()); i++)
885    {
886      BObjClassify oc(last_->GetCastings()[i], BOBJECTMODE);
887      f = obch->find(oc);
888      if(f!=obch->end()) { found = f->second; }
889    }
890    if(!found)
891    {
892      BArray<BSyntaxObject*> options;
893      for(f=obch->begin(); f!=obch->end(); f++)
894      {
895        if(f->second->Mode()!=BOBJECTMODE) { continue; }
896        if(!found)
897        {
898          found = f->second;
899        }
900        else if(BSymbolTable::AreCompatible(found,f->second))
901        {
902          options.Add(f->second);
903        }
904      }
905      if(options.Size())
906      {
907        BGrammarId gPos = found->Grammar()->Gid();
908        BText another = "";
909        for(i=0; i<options.Size(); i++)
910        {
911          another << BText("  ")+options[i]->LexInfo()+";\n";
912          if(found->Grammar()->Precedence()>options[i]->Grammar()->Precedence())
913          {
914            found = options[i];
915          }
916        }
917        Warning(I2("Variable symbol ", "El símbolo de variable ")+name+
918                I2(" is ambiguous.",   " es ambiguo.")+"\n"+
919                found->LexInfo()+"\n;"+
920                I2(" has been selected but there are this other ",
921                " ha sido elegido pero había otras ")+options.Size()+":\n"+
922                another);
923      }
924    }
925  }
926  if(!found)  { found = BNameBlock::UsingMember(name);  }
927  return(found);
928}
929
930
931//--------------------------------------------------------------------
932BOperator* BAnyGrammar::FindOperator(const BText& name) const
933
934/*! Finds an object named name in any grammar.
935 */
936//--------------------------------------------------------------------
937{
938  int i;
939  BOperator* found = NULL;
940  if(!found) { found = getOperator(this, BNameBlock::LocalMember(name)); }
941  if(!found) { found = getOperator(this, FindLocal(name)); }
942  BObjByClassHash* obch;
943  BObjByClassHash::const_iterator f;
944  if(!found && (obch = symbolTable_->Search(name)) && obch->size())
945  {
946    BObjClassify oc(last_, BUSERFUNMODE);
947    f = obch->find(oc);
948    if(f!=obch->end()) { found = (BOperator*)f->second; }
949    for(i=0; !found && (i<last_->GetCastings().Size()); i++)
950    {
951      BObjClassify oc(last_->GetCastings()[i], BUSERFUNMODE);
952      f = obch->find(oc);
953      if(f!=obch->end()) { found = (BOperator*)f->second; }
954    }
955    if(!found)
956    {
957      BArray<BSyntaxObject*> options;
958      for(f=obch->begin(); f!=obch->end(); f++)
959      {
960        const BGrammar* g = f->first.grammar_;
961        int             m = f->first.mode_;
962        if(!found)
963        {
964          if(m==BUSERFUNMODE)
965          {
966            found = (BOperator*)f->second;
967          }
968          else if(g==GraCode())
969          {
970            BUserCode* code = UCode(f->second);
971            if(code) { found = code->Contens().Operator(); }
972          }
973        }
974        if(found && (BSymbolTable::AreCompatible(found,f->second))&&
975           (m==BUSERFUNMODE))
976        {
977          options.Add(f->second);
978        }
979      }
980      if(options.Size())
981      {
982        BText another = "";
983        for(i=0; i<options.Size(); i++)
984        {
985          another << BText("  ")+options[i]->LexInfo()+";\n";
986          if(found->Grammar()->Precedence()>options[i]->Grammar()->Precedence())
987          {
988            found = (BOperator*)options[i];
989          }
990        }
991        Warning(I2("Function symbol ", "El símbolo de función ")+name+
992                I2(" is ambiguous.",   " es ambiguo.")+"\n"+
993                found->LexInfo()+"\n;"+
994                I2(" has been selected but there were these other ",
995                   " ha sido elegido pero había estas otras ")+options.Size()+
996                I2(" options"," opciones")+":\n"+another);
997      }
998    }
999  }
1000  if(!found)
1001  {
1002    found = getOperator(this, BNameBlock::UsingMember(name));
1003  }
1004  return(found);
1005}
1006
1007
1008//--------------------------------------------------------------------
1009BSyntaxObject* BAnyGrammar::New(const BText& name,
1010              BSyntaxObject* syn) const
1011//--------------------------------------------------------------------
1012{
1013    BSyntaxObject* result = NIL;
1014    if(syn)
1015    {
1016  if(syn->Grammar() != (BGrammar*)this)
1017  {
1018      result = syn->Grammar()->New(name, syn);
1019  }
1020  else
1021  {
1022      result = syn;
1023  }
1024    }
1025    return(result);
1026}
1027
1028
1029//--------------------------------------------------------------------
1030BSyntaxObject* BAnyGrammar::NewFunArg(const BText& localName,
1031                              BSyntaxObject* syn) const
1032//--------------------------------------------------------------------
1033{
1034    BSyntaxObject* result = NIL;
1035    if(syn)
1036    {
1037  if(syn->Grammar() != (BGrammar*)this)
1038  {
1039      result = syn->Grammar()->NewFunArg(localName, syn);
1040  }
1041  else
1042  {
1043      result = syn;
1044  }
1045    }
1046    return(result);
1047}
1048
1049
1050//--------------------------------------------------------------------
1051BBool BAnyGrammar::InitGrammar()
1052
1053/*! Initializes the Anything grammar.
1054 */
1055//--------------------------------------------------------------------
1056{
1057    if(!anyGrammar_) { anyGrammar_ = new BAnyGrammar; }
1058    return(BTRUE);
1059}
1060
1061
1062//--------------------------------------------------------------------
1063/* Static methods to Turn On/Off stopFlag_ attribute,
1064 * used to stop evaluation process
1065 */
1066void BGrammar::Turn_StopFlag_On()  { BGrammar::stopFlag_ = true;  }
1067void BGrammar::Turn_StopFlag_Off() { BGrammar::stopFlag_ = false; }
Note: See TracBrowser for help on using the repository browser.