Main Page | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Class Members | File Members

lcont.cpp

Go to the documentation of this file.
00001 // +-------------------------------------------------------------------------+
00002 // |               I__n__t__e__L__i__b           0.6.10 development          |
00003 // | Copyright (c) Andrey Vikt. Stolyarov <crocodil_AT_croco.net> 2000-2007. |
00004 // |                                                                         |
00005 // | This is free software. The library part is available under              |
00006 // |                               GNU LESSER GENERAL PUBLIC LICENSE v.2.1.  |
00007 // | GNU LGPL v2.1 is found in docs/gnu_gpl2.txt,  or at  http://www.gnu.org |
00008 // |     Please see also docs/readme.txt and visit http://www.intelib.org    |
00009 // |                                                                         |
00010 // | !!! THERE IS NO WARRANTY OF ANY KIND, NEITHER EXPRESSED NOR IMPLIED !!! |
00011 // +-------------------------------------------------------------------------+
00012 
00013 
00014 
00015 
00016 #include "../sexpress/iexcept.hpp"
00017 #include "../sexpress/sstring.hpp"
00018 #include "lisp.hpp"
00019 #include "lcont.hpp"
00020 #include "lsymbol.hpp"
00021 #include "llambda.hpp"
00022 
00023 
00025 
00026 IntelibTypeId LExpressionContext::TypeId(&SExpression::TypeId, false);
00027 
00028 LExpressionContext::LExpressionContext()
00029     : SExpression(TypeId)
00030 {}
00031 
00032 LExpressionContext::LExpressionContext(LContextRef a_prev)
00033     : SExpression(TypeId), prev(a_prev)
00034 {}
00035 
00036 LExpressionContext::~LExpressionContext()
00037 {}
00038 
00039 void LExpressionContext::AddBinding(const LExpressionSymbol *symb,
00040                                     const SReference& val)
00041 {
00042     (*valtbl.AddBinding((unsigned long)symb)) = val;
00043 }
00044 
00045 SReference*
00046 LExpressionContext::GetBinding(const LExpressionSymbol *symb) const
00047 {
00048     SReference *res = valtbl.GetBinding((unsigned long)symb);
00049     if(res) return res;
00050     if(prev.GetPtr()) {
00051         return prev->GetBinding(symb);
00052     } else {
00053         return 0;
00054     }
00055 }
00056 
00057 SReference*
00058 LExpressionContext::ProvideBinding(const LExpressionSymbol *symb)
00059 {
00060     SReference *res = GetBinding(symb);
00061     if(!res) res = valtbl.AddBinding((unsigned long)symb);
00062     return res;
00063 }
00064 
00065 void LExpressionContext::AddFunBinding(const LExpressionSymbol *symb,
00066                                        const SReference& val)
00067 {
00068     (*funtbl.AddBinding((unsigned long)symb)) = val;
00069 }
00070 
00071 SReference*
00072 LExpressionContext::GetFunBinding(const LExpressionSymbol *symb) const
00073 {
00074     SReference *res = funtbl.GetBinding((unsigned long)symb);
00075     if(res) return res;
00076     if(prev.GetPtr()) {
00077         return prev->GetFunBinding(symb);
00078     } else {
00079         return 0;
00080     }
00081 }
00082 
00083 SReference*
00084 LExpressionContext::ProvideFunBinding(const LExpressionSymbol *symb)
00085 {
00086     SReference *res = GetBinding(symb);
00087     if(!res) res = funtbl.AddBinding((unsigned long)symb);
00088     return res;
00089 }
00090 
00091 
00092 SReference LExpressionContext::GetAllSymbols() const
00093 {
00094     SReference ret;
00095     if(prev.GetPtr()) {
00096         ret = prev->GetAllSymbols();
00097     } else {
00098         ret = *PTheEmptyList;
00099     }
00100     //
00101     {
00102         IntelibBindTable::Iterator iter(valtbl);
00103         unsigned long key;
00104         SReference t;
00105         while(iter.GetNext(key, t)) {
00106             ret = SReference((LExpressionSymbol*)key, ret);
00107         }
00108     }
00109     //
00110     {
00111         IntelibBindTable::Iterator iter(funtbl);
00112         unsigned long key;
00113         SReference t;
00114         while(iter.GetNext(key, t)) {
00115             ret = SReference((LExpressionSymbol*)key, ret);
00116         }
00117     }
00118     return ret;
00119 }
00120 
00121 SString LExpressionContext::TextRepresentation() const
00122 {
00123     return "#<LISP-CONTEXT>";
00124 }
00125 
00127 
00128 void LispContinuation::CustomCommand(int opcode, const SReference& param)
00129 {
00130     switch(opcode) {
00131         case take_result_as_form: {
00132             SReference r;
00133             PopResult(r);
00134             PushTodo(just_evaluate, r);
00135             break;
00136         }
00137         case duplicate_last_result: {
00138             SReference r;
00139             PopResult(r);
00140             PushResult(r);
00141             PushResult(r);
00142             break;
00143         }
00144         default:
00145                 // this will just throw an exception
00146             IntelibContinuation::CustomCommand(opcode, param);
00147     }
00148 }
00149 
00150 void LispContinuation::JustEvaluate(const SReference& expr)
00151 {
00152     if(!expr.GetPtr()) throw IntelibX_unexpected_unbound_value();
00153     const IntelibTypeId *t;
00154     for(t=&(expr->TermType()); t; t=t->Prev()) {
00155         if(*t == SExpressionCons::TypeId) {
00156             EvaluateForm(static_cast<SExpressionCons*>(expr.GetPtr()));
00157             return;
00158         } else
00159         if(*t == LExpressionSymbol::TypeId) {
00160             LExpressionSymbol *sym =
00161                 static_cast<LExpressionSymbol*>(expr.GetPtr());
00162             if(sym->IsDynamic()) {
00163                 if(sym->IsConstant()) {
00164                     RegularReturn(sym->GetDynamicValue());
00165                 } else {
00166                     ReferenceReturn(sym->GetDynamicValueRef(), expr);
00167                 }
00168             } else {
00169                 SReference &res = GetSymbolValue(sym); 
00170                 if(!res.GetPtr())
00171                     throw IntelibX_lisp_symbol_has_no_value(expr);
00172                 ReferenceReturn(res, expr);
00173             }
00174             return;
00175         }
00176     }
00177     // no parent means that it's a regular constant...
00178     // it is always self-evaluated
00179     PushResult(expr);
00180 }
00181 
00182 #if 0
00183 void LispContinuation::DoFunctionCall(const SReference &fun_ref,
00184                                      int paramscount,
00185                                      const SReference *paramsvector)
00186 {
00187     LExpressionFunction *fun =
00188         fun_ref.DynamicCastGetPtr<LExpressionFunction>();
00189     if(!fun) {
00190         throw IntelibX_lisp_not_a_function(fun_ref);
00191     }
00192     fun->Apply(paramscount, paramsvector, *this);
00193 }
00194 #endif
00195 
00196 // not static because is used by LFunctionFunction
00197 LReference RetrieveFunctionObject(LReference from, 
00198                                   const LContextRef &lc) 
00199 {
00200     const LExpressionSymbol *symb =
00201         from.DynamicCastGetPtr<LExpressionSymbol>();
00202     if(symb) {
00203         const SReference *tmp = 0; 
00204         if(lc.GetPtr())
00205             tmp = lc->GetFunBinding(symb);
00206         if(!tmp || !tmp->GetPtr())
00207             tmp = &symb->GetFunction();
00208         if(tmp->GetPtr()) {
00209             return *tmp;
00210         }
00211         throw IntelibX_no_associated_function(from);
00212     }
00213 
00214     SExpressionCons *dp = 
00215         from.DynamicCastGetPtr<SExpressionCons>();
00216     if(dp) {
00217         if(dp->Car() == *PTheLispSymbolLambda) {
00218             LReference tmp = dp->Cdr(); 
00219             return LReference(new LExpressionLambda(lc, tmp.Car(), 
00220                                                     tmp.Cdr()));
00221         }
00222         throw IntelibX_no_associated_function(from);
00223     }      
00224     
00225     SExpressionFunction *fn = from.DynamicCastGetPtr<SExpressionFunction>();
00226     if(fn) return from;
00227 
00228     SExpressionForm *frm = from.DynamicCastGetPtr<SExpressionForm>();
00229     if(frm) return frm;
00230 
00231     throw IntelibX_no_associated_function(from);
00232 }
00233 
00234 void LispContinuation::EvaluateForm(SExpressionCons *form)
00235 {
00236     LReference fun = RetrieveFunctionObject(form->Car(), GetContext());
00237     SExpressionForm *f = fun.DynamicCastGetPtr<SExpressionForm>();
00238     if(f) { // special symbol
00239         f->Call(form->Cdr(), *this);
00240     } else {
00241         PushResult(fun);
00242         SExpressionCons *cdr =
00243             form->Cdr().DynamicCastGetPtr<SExpressionCons>();
00244         if(cdr) {
00245             PlaceFormToStack(cdr, 1);
00246         } else {
00247             PushTodo(0);
00248         }
00249     }
00250 }
00251 
00252 SReference& LispContinuation::GetSymbolValue(LExpressionSymbol *sym) const
00253 {
00254     SReference *lexval = 0;
00255     if(GetContext().GetPtr()) {
00256         lexval = GetContext()->GetBinding(sym);
00257     }
00258     if(lexval)
00259         return *lexval;
00260     else
00261         return sym->GetDynamicValueRef();
00262 }
00263 
00264 IntelibX_lisp_not_a_function::
00265 IntelibX_lisp_not_a_function(SReference a_param) 
00266     : IntelibX("lisp: not a function", a_param) {}
00267 
00268 IntelibX_lisp_not_a_context::
00269 IntelibX_lisp_not_a_context(SReference a_param) 
00270     : IntelibX("lisp: not a context", a_param) {}
00271 
00272 IntelibX_lisp_symbol_has_no_value::
00273 IntelibX_lisp_symbol_has_no_value(SReference a_param) 
00274     : IntelibX("lisp: symbol has no value", a_param) {}
00275 
00276 IntelibX_no_associated_function::
00277 IntelibX_no_associated_function(SReference a_param) 
00278     : IntelibX("No associated function", a_param) {}

Generated on Tue Dec 18 00:39:43 2007 for InteLib by  doxygen 1.4.1