00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
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
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
00178
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
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) {
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) {}