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

llambda.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/sstring.hpp"
00017 #include "../sexpress/slocatn.hpp"
00018 #include "lcont.hpp"
00019 #include "lsymbol.hpp"
00020 #include "llambda.hpp"
00021 
00022 
00023 LispLambdaBody::LispLambdaBody(const LContextRef &a_cx,
00024                                const SReference &a_lambda,
00025                                const SReference &a_body)
00026     : context(a_cx), lambda_list(a_lambda), body(a_body)
00027 {
00028     DoAnalyseLambdaList(a_lambda, 0);
00029 }
00030 
00031 LispLambdaBody::~LispLambdaBody()
00032 {
00033     delete[] lambda_vector;
00034 }
00035 
00036 void LispLambdaBody::DoAnalyseLambdaList(const SReference &rest, int n)
00037 {
00038     SExpressionCons *dp = rest.DynamicCastGetPtr<SExpressionCons>();
00039     if(dp) {
00040         DoAnalyseLambdaList(dp->Cdr(), n+1);
00041         lambda_vector[n] =
00042             static_cast<LExpressionSymbol*>(dp->Car().GetPtr());
00043         INTELIB_ASSERT(dp->Car().DynamicCastGetPtr<LExpressionSymbol>(),
00044                        IntelibX_lisp_not_a_symbol(dp->Car()));
00045     } else {
00046         lambda_vector = new LExpressionSymbol* [n];
00047         lambda_length = n;
00048         if(rest.IsEmptyList()) {
00049             lambda_rest = 0;
00050         } else {
00051             lambda_rest = 
00052                 static_cast<LExpressionSymbol*>(rest.GetPtr());
00053             INTELIB_ASSERT(rest.DynamicCastGetPtr<LExpressionSymbol>(),
00054                            IntelibX_lisp_not_a_symbol(dp->Car()));
00055         }
00056     }
00057 }
00058 
00060 
00061 
00062 IntelibTypeId LExpressionLambda::TypeId(&SExpressionFunction::TypeId);
00063 
00064 LExpressionLambda::LExpressionLambda(const LContextRef &cx,
00065                                      const SReference &lambda,
00066                                      const SReference &body)
00067     : SExpressionFunction(TypeId, -1, -1), LispLambdaBody(cx, lambda, body)
00068 {
00069     min_param = lambda_length;
00070     max_param = lambda_rest ? -1 : lambda_length;
00071 }
00072 
00073 LExpressionLambda::~LExpressionLambda()
00074 {}
00075 
00076 static void do_bind_symbol(LExpressionSymbol *symb,
00077                            const SReference &value,
00078                            LContextRef &context,
00079                            IntelibContinuation &lf)
00080 {
00081     if(symb->IsDynamic()) {
00082         lf.PushTodo(
00083             IntelibContinuation::assign_to,
00084             new SExpressionLocation(symb, &(symb->GetDynamicValueRef()))
00085         );
00086         lf.PushTodo(
00087             IntelibContinuation::quote_parameter,
00088             symb->GetDynamicValue()
00089         );
00090         symb->SetDynamicValue(value);
00091     } else {
00092         context->AddBinding(symb, value);
00093     }
00094 }
00095 
00096 void LExpressionLambda::DoApply(int paramc, const SReference *paramv,
00097                                 IntelibContinuation &lf) const
00098 {
00099     LContextRef tempcontext(new LExpressionContext(context));
00100     for(int i = 0; i<min_param; i++) {
00101         //tempcontext->AddBinding(lambda_vector[i], paramv[i]);
00102         do_bind_symbol(lambda_vector[i], paramv[i], tempcontext, lf);
00103     }
00104     if(lambda_rest) {
00105         SReference ls(*PTheEmptyList);
00106         for(int i=paramc-1; i>=min_param; i--)
00107             ls = SReference(paramv[i], ls);
00108         //tempcontext->AddBinding(lambda_rest, ls);
00109         do_bind_symbol(lambda_rest, ls, tempcontext, lf);
00110     }
00111 
00112     lf.PushTodo(LispContinuation::set_context, lf.GetContext());
00113     lf.PushTodo(LispContinuation::evaluate_progn, body);
00114     lf.PushTodo(LispContinuation::set_context, tempcontext);
00115 }
00116 
00117 #if INTELIB_TEXT_REPRESENTATIONS == 1
00118 SString LExpressionLambda::TextRepresentation() const
00119 {
00120     SString str("#<CLOSURE ");
00121     str += lambda_list->TextRepresentation();
00122     str += body->TextRepresentation();
00123     str += ">";
00124     return str;
00125 }
00126 #endif
00127 
00129 
00130 
00131 IntelibTypeId LExpressionMacro::TypeId(&SExpressionForm::TypeId);
00132 
00133 LExpressionMacro::LExpressionMacro(const LContextRef &cx,
00134                                      const SReference &lambda,
00135                                      const SReference &body)
00136     : SExpressionForm(TypeId), LispLambdaBody(cx, lambda, body)
00137 {}
00138 
00139 LExpressionMacro::~LExpressionMacro()
00140 {}
00141 
00142 void LExpressionMacro::Call(const SReference &params,
00143                             IntelibContinuation &lf) const
00144 {
00145     LContextRef tempcontext(new LExpressionContext(context));
00146     const SReference *p = &params;
00147     for(int i = 0; i<lambda_length; i++) {
00148         //tempcontext->AddBinding(lambda_vector[i], p->Car());
00149         do_bind_symbol(lambda_vector[i], p->Car(), tempcontext, lf);
00150         p = &(p->Cdr());
00151     }
00152     if(lambda_rest) {
00153         //tempcontext->AddBinding(lambda_rest, *p);
00154         do_bind_symbol(lambda_rest, *p, tempcontext, lf);
00155     } else {
00156         if(!p->IsEmptyList()) {
00157             throw IntelibX_too_many_params(*p);
00158         }
00159     }
00160 
00161     lf.PushTodo(LispContinuation::take_result_as_form);
00162     lf.PushTodo(LispContinuation::set_context, lf.GetContext());
00163     lf.PushTodo(LispContinuation::evaluate_progn, body);
00164     lf.PushTodo(LispContinuation::set_context, tempcontext);
00165 }
00166 
00167 #if INTELIB_TEXT_REPRESENTATIONS == 1
00168 SString LExpressionMacro::TextRepresentation() const
00169 {
00170     SString str("#<MACRO ");
00171     str += lambda_list->TextRepresentation();
00172     str += body->TextRepresentation();
00173     str += ">";
00174     return str;
00175 }
00176 #endif
00177 
00179 
00180 
00181 IntelibTypeId
00182 LExpressionUserCFunction::TypeId(&SExpressionFunction::TypeId);
00183 
00184 #if INTELIB_TEXT_REPRESENTATIONS == 1
00185 SString LExpressionUserCFunction::TextRepresentation() const
00186 {
00187     return "#<USER-DEFINED FUNCTION>";
00188 }
00189 #endif

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