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 "lcont.hpp" 00018 //#include "lsymbol.hpp" 00019 #include "llambda.hpp" 00020 00021 #include "lisp.hpp" 00022 00023 00024 LReference::LReference(UserLispFunction fun) 00025 : SReference(new LExpressionUserCFunction(fun)) 00026 {} 00027 00028 LReference LReference::Evaluate() const 00029 { 00030 LispContinuation cont; 00031 return Evaluate(cont); 00032 } 00033 00034 LReference LReference::Evaluate(LispContinuation &cont) const 00035 { 00036 int mark = cont.GetMark(); 00037 cont.PushTodo(LispContinuation::just_evaluate, *this); 00038 while(!cont.Ready(mark)) 00039 cont.Step(); 00040 return cont.Get(); 00041 } 00042 00043 bool LReference::IsEql(const SReference& other) const 00044 { 00045 if(GetPtr()==other.GetPtr()) return true; 00046 if(!GetPtr() || !other.GetPtr()) return false; 00047 if(GetPtr()->TermType() != other.GetPtr()->TermType()) return false; 00048 return GetPtr()->SpecificEql(other.GetPtr()); 00049 } 00050 00051 bool LReference::IsEqual(const SReference& other) const 00052 { 00053 if(IsEql(other)) return true; 00054 SExpressionCons *dp1 = DynamicCastGetPtr<SExpressionCons>(); 00055 SExpressionCons *dp2 = dp1 ? 00056 other.DynamicCastGetPtr<SExpressionCons>() : 0; 00057 if(dp1 && dp2) { 00058 return LReference(dp1->Car()).IsEqual(dp2->Car()) && 00059 LReference(dp1->Cdr()).IsEqual(dp2->Cdr()); 00060 } else { 00061 return false; 00062 } 00063 } 00064 00065 #if INTELIB_TEXT_REPRESENTATIONS == 1 00066 static SString LReferenceTextRepresentationCallBack(const SReference& ex) 00067 { 00068 return LReference(ex).TextRepresentation(); 00069 } 00070 00071 SString LReference::TextRepresentation() const 00072 { 00073 if(!GetPtr()) return "#<UNBOUND>"; 00074 if(GetPtr()->TermType()==SExpressionCons::TypeId) { 00075 SExpressionCons *dp = static_cast<SExpressionCons*>(GetPtr()); 00076 if(dp->Car().GetPtr() == PTheLispSymbolQuote->GetPtr()) { 00077 // QUOTE form... check that there's one argument 00078 if(dp->Cdr().GetPtr()->TermType()==SExpressionCons::TypeId) { 00079 SExpressionCons *dp2 = 00080 static_cast<SExpressionCons*>(dp->Cdr().GetPtr()); 00081 if(dp2->Cdr().IsEmptyList()) { 00082 // YES! 00083 return SString("\'") + 00084 LReference(dp2->Car()).TextRepresentation(); 00085 } 00086 } 00087 } else 00088 if(dp->Car().GetPtr() == PTheLispSymbolFunction->GetPtr()) { 00089 // FUNCTION form... check that there's one argument 00090 if(dp->Cdr().GetPtr()->TermType()==SExpressionCons::TypeId) { 00091 SExpressionCons *dp2 = 00092 static_cast<SExpressionCons*>(dp->Cdr().GetPtr()); 00093 if(dp2->Cdr().IsEmptyList()) { 00094 // YES! 00095 return SString("#\'") + 00096 LReference(dp2->Car()).TextRepresentation(); 00097 } 00098 } 00099 } 00100 // seem not to be QUOTE nor FUNCTION form, but it may contain them... 00101 return SString("(") + 00102 dp->CoreTextRepresentation(" ", " . ", 00103 LReferenceTextRepresentationCallBack) + 00104 SString(")"); 00105 } 00106 return GetPtr()->TextRepresentation(); 00107 } 00108 #endif 00109 00110 static LReference JustAnUnboundLReferenceObject; 00111 00112 SReference *PTheLispSymbolLambda = &JustAnUnboundLReferenceObject; 00113 SReference *PTheLispSymbolQuote = &JustAnUnboundLReferenceObject; 00114 SReference *PTheLispSymbolFunction = &JustAnUnboundLReferenceObject; 00115 SReference *PTheLispBooleanTrue = &JustAnUnboundLReferenceObject; 00116 SReference *PTheLispBooleanFalse = &JustAnUnboundLReferenceObject;