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 "schcont.hpp" 00018 #include "scheme.hpp" 00019 00020 SchReference SchReference::Evaluate() const 00021 { 00022 SchemeContinuation cont; 00023 return Evaluate(cont); 00024 } 00025 00026 SchReference SchReference::Evaluate(SchemeContinuation &cont) const 00027 { 00028 int mark = cont.GetMark(); 00029 cont.PushTodo(SchemeContinuation::just_evaluate, *this); 00030 while(!cont.Ready(mark)) 00031 cont.Step(); 00032 return cont.Get(); 00033 } 00034 00035 bool SchReference::IsEql(const SReference& other) const 00036 { 00037 // this is exactly the same code as for LReference 00038 // perhaps I should move it somewhere to sexpress/ 00039 if(GetPtr()==other.GetPtr()) return true; 00040 if(!GetPtr() || !other.GetPtr()) return false; 00041 if(GetPtr()->TermType() != other.GetPtr()->TermType()) return false; 00042 return GetPtr()->SpecificEql(other.GetPtr()); 00043 } 00044 00045 bool SchReference::IsEqual(const SReference& other) const 00046 { 00047 // this is exactly the same code as for LReference 00048 // perhaps I should move it somewhere to sexpress/ 00049 if(IsEql(other)) return true; 00050 SExpressionCons *dp1 = DynamicCastGetPtr<SExpressionCons>(); 00051 SExpressionCons *dp2 = dp1 ? 00052 other.DynamicCastGetPtr<SExpressionCons>() : 0; 00053 if(dp1 && dp2) { 00054 return SchReference(dp1->Car()).IsEqual(dp2->Car()) && 00055 SchReference(dp1->Cdr()).IsEqual(dp2->Cdr()); 00056 } else { 00057 return false; 00058 } 00059 } 00060 00061 #if INTELIB_TEXT_REPRESENTATIONS == 1 00062 static SString SchReferenceTextRepresentationCallBack(const SReference& ex) 00063 { 00064 return SchReference(ex).TextRepresentation(); 00065 } 00066 00067 SString SchReference::TextRepresentation() const 00068 { 00069 // this code is almost the same as for LReference 00070 // sorry guys I know it's not wise to copy&paste, but I couldn't 00071 // invent a better way to accomplish this 00072 if(!GetPtr()) return "#<UNBOUND>"; 00073 if(GetPtr()->TermType()==SExpressionCons::TypeId) { 00074 SExpressionCons *dp = static_cast<SExpressionCons*>(GetPtr()); 00075 if(dp->Car().GetPtr() == PTheSchemeSymbolQuote->GetPtr()) { 00076 // QUOTE form... check that there's one argument 00077 if(dp->Cdr().GetPtr()->TermType()==SExpressionCons::TypeId) { 00078 SExpressionCons *dp2 = 00079 static_cast<SExpressionCons*>(dp->Cdr().GetPtr()); 00080 if(dp2->Cdr().IsEmptyList()) { 00081 // YES! 00082 return SString("\'") + 00083 SchReference(dp2->Car()).TextRepresentation(); 00084 } 00085 } 00086 } 00087 // seem not to be QUOTE form, but it may contain them... 00088 return SString("(") + 00089 dp->CoreTextRepresentation(" ", " . ", 00090 SchReferenceTextRepresentationCallBack) + 00091 SString(")"); 00092 } 00093 return GetPtr()->TextRepresentation(); 00094 } 00095 #endif 00096 00097 00098 00099 static SReference JustAnUnboundReferenceObject; 00100 00101 SReference *PTheSchemeSymbolQuote = &JustAnUnboundReferenceObject; 00102 SReference *PTheSchemeBooleanTrue = &JustAnUnboundReferenceObject; 00103 SReference *PTheSchemeBooleanFalse = &JustAnUnboundReferenceObject; 00104