00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #include "../sexpress/sstring.hpp"
00017 #include "schcont.hpp"
00018 #include "schsymb.hpp"
00019 #include "schfun.hpp"
00020
00021 IntelibTypeId SchExpressionLambda::TypeId(&SExpressionFunction::TypeId);
00022
00023 SchExpressionLambda::SchExpressionLambda(const SchContextRef &a_cx,
00024 const SReference &a_lambda,
00025 const SReference &a_body)
00026 : SExpressionFunction(TypeId, -1, -1),
00027 context(a_cx), lambda_list(a_lambda), body(a_body)
00028 {
00029 DoAnalyseLambdaList(a_lambda, 0);
00030 }
00031
00032 SchExpressionLambda::~SchExpressionLambda()
00033 {
00034 delete[] lambda_vector;
00035 }
00036
00037 void SchExpressionLambda::DoApply(int paramc, const SReference *paramv,
00038 IntelibContinuation &lf) const
00039 {
00040 SchContextRef tempcontext(new SchExpressionContext(context));
00041 for(int i = 0; i<min_param; i++) {
00042 tempcontext->AddBinding(lambda_vector[i], paramv[i]);
00043 }
00044 if(lambda_rest) {
00045 SReference ls(*PTheEmptyList);
00046 for(int i=paramc-1; i>=min_param; i--)
00047 ls = SReference(paramv[i], ls);
00048 tempcontext->AddBinding(lambda_rest, ls);
00049 }
00050
00051 lf.PushTodo(SchemeContinuation::set_context, lf.GetContext());
00052 lf.PushTodo(SchemeContinuation::evaluate_progn, body);
00053 lf.PushTodo(SchemeContinuation::set_context, tempcontext);
00054 }
00055
00056 void SchExpressionLambda::DoAnalyseLambdaList(const SReference &rest, int n)
00057 {
00058 SExpressionCons *dp = rest.DynamicCastGetPtr<SExpressionCons>();
00059 if(dp) {
00060 DoAnalyseLambdaList(dp->Cdr(), n+1);
00061 lambda_vector[n] =
00062 static_cast<SchExpressionSymbol*>(dp->Car().GetPtr());
00063 INTELIB_ASSERT(dp->Car().DynamicCastGetPtr<SchExpressionSymbol>(),
00064 IntelibX_scheme_not_a_symbol(dp->Car()));
00065 } else {
00066 lambda_vector = new SchExpressionSymbol* [n];
00067 min_param = n;
00068 if(rest.IsEmptyList()) {
00069 max_param = n;
00070 lambda_rest = 0;
00071 } else {
00072 max_param = -1;
00073 lambda_rest =
00074 static_cast<SchExpressionSymbol*>(rest.GetPtr());
00075 INTELIB_ASSERT(rest.DynamicCastGetPtr<SchExpressionSymbol>(),
00076 IntelibX_scheme_not_a_symbol(dp->Car()));
00077 }
00078 }
00079 }
00080
00081 #if 0
00082 void SchExpressionLambda::DoPushBody(const SReference &rest,
00083 SchemeContinuation &cont)
00084 {
00085 if(rest.IsEmptyList()) return;
00086 DoPushBody(rest.Cdr(), cont);
00087 cont.PushTodo(SchemeContinuation::just_evaluate, rest.Car());
00088 }
00089 #endif
00090
00091 #if INTELIB_TEXT_REPRESENTATIONS == 1
00092 SString SchExpressionLambda::TextRepresentation() const
00093 {
00094 SString str("#<CLOSURE ");
00095 str += lambda_list->TextRepresentation();
00096 str += body->TextRepresentation();
00097 str += ">";
00098 return str;
00099 }
00100 #endif
00101