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 "scheme.hpp"
00019 #include "schcont.hpp"
00020 #include "schsymb.hpp"
00021 #include "schfun.hpp"
00022
00023
00025
00026 IntelibTypeId SchExpressionContext::TypeId(&SExpression::TypeId, false);
00027
00028 SchExpressionContext::SchExpressionContext()
00029 : SExpression(TypeId)
00030 {}
00031
00032 SchExpressionContext::SchExpressionContext(SchContextRef a_prev)
00033 : SExpression(TypeId), prev(a_prev)
00034 {}
00035
00036 SchExpressionContext::~SchExpressionContext()
00037 {}
00038
00039 void SchExpressionContext::AddBinding(const SchExpressionSymbol *symb,
00040 const SReference& val)
00041 {
00042 (*tbl.AddBinding((unsigned long)symb)) = val;
00043 }
00044
00045 SReference*
00046 SchExpressionContext::GetBinding(const SchExpressionSymbol *symb) const
00047 {
00048 SReference *res = tbl.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 SchExpressionContext::ProvideBinding(const SchExpressionSymbol *symb)
00059 {
00060 SReference *res = GetBinding(symb);
00061 if(!res) res = tbl.AddBinding((unsigned long)symb);
00062 return res;
00063 }
00064
00065 SReference SchExpressionContext::GetAllSymbols() const
00066 {
00067 SReference ret;
00068 if(prev.GetPtr()) {
00069 ret = prev->GetAllSymbols();
00070 } else {
00071 ret = *PTheEmptyList;
00072 }
00073 IntelibBindTable::Iterator iter(tbl);
00074 unsigned long key;
00075 SReference t;
00076 while(iter.GetNext(key, t)) {
00077 ret = SReference((SchExpressionSymbol*)key, ret);
00078 }
00079 return ret;
00080 }
00081
00082 SString SchExpressionContext::TextRepresentation() const
00083 {
00084 return "#<SCHEME-CONTEXT>";
00085 }
00086
00088
00089 void SchemeContinuation::CustomCommand(int opcode, const SReference& param)
00090 {
00091 switch(opcode) {
00092 case case_check:
00093 CaseCheck(param);
00094 break;
00095 default:
00096
00097 IntelibContinuation::CustomCommand(opcode, param);
00098 }
00099 }
00100
00101 static bool eqv_memberp(const SReference &a, const SReference &ls)
00102 {
00103 SExpressionCons *dp = ls.DynamicCastGetPtr<SExpressionCons>();
00104 if(!dp) return false;
00105 return a.IsEql(dp->Car()) || eqv_memberp(a, dp->Cdr());
00106 }
00107
00108 void SchemeContinuation::CaseCheck(const SReference& expr)
00109 {
00110 SReference val;
00111 PopResult(val);
00112 if(eqv_memberp(val, expr)) {
00113
00114 PushResult(*PTheSchemeBooleanTrue);
00115 } else {
00116
00117 PushResult(val);
00118 PushResult(*PTheSchemeBooleanFalse);
00119 }
00120 }
00121
00122 void SchemeContinuation::JustEvaluate(const SReference& expr)
00123 {
00124 if(!expr.GetPtr()) throw IntelibX_unexpected_unbound_value();
00125 const IntelibTypeId *t;
00126 for(t=&(expr->TermType()); t; t=t->Prev()) {
00127 if(*t == SExpressionCons::TypeId) {
00128 EvaluateForm(static_cast<SExpressionCons*>(expr.GetPtr()));
00129 return;
00130 } else
00131 if(*t == SchExpressionSymbol::TypeId) {
00132 SchExpressionSymbol *sym =
00133 static_cast<SchExpressionSymbol*>(expr.GetPtr());
00134 SReference &res = GetSymbolValue(sym);
00135 if(!res.GetPtr())
00136 throw IntelibX_scheme_symbol_has_no_value(expr);
00137 ReferenceReturn(res, expr);
00138 return;
00139 }
00140 }
00141
00142
00143 PushResult(expr);
00144 }
00145
00146 #if 0
00147 void SchemeContinuation::DoFunctionCall(const SReference &fun_ref,
00148 int paramscount,
00149 const SReference *paramsvector)
00150 {
00151 SExpressionFunction *fun =
00152 fun_ref.DynamicCastGetPtr<SExpressionFunction>();
00153 if(!fun) {
00154 throw IntelibX_scheme_not_a_function(fun_ref);
00155 }
00156 fun->Apply(paramscount, paramsvector, *this);
00157 }
00158 #endif
00159
00160
00161 void SchemeContinuation::EvaluateForm(SExpressionCons *form)
00162 {
00163 #if 0 // INTELIB_CONTINUATION_KEEPS_STACK_INFO == 1
00164 int keepstack_position = todo_stack_pointer;
00165 #endif
00166 SchExpressionSymbol *sym =
00167 form->Car().DynamicCastGetPtr<SchExpressionSymbol>();
00168 if(sym) {
00169 SReference &val = GetSymbolValue(sym);
00170 if(!val.GetPtr())
00171 throw IntelibX_scheme_symbol_has_no_value(form->Car());
00172 SExpressionForm *f = val.DynamicCastGetPtr<SExpressionForm>();
00173 if(f) {
00174 f->Call(form->Cdr(), *this);
00175 } else {
00176 PushResult(val);
00177 SExpressionCons *cdr =
00178 form->Cdr().DynamicCastGetPtr<SExpressionCons>();
00179 if(cdr) {
00180 PlaceFormToStack(cdr, 1);
00181 } else {
00182 PushTodo(0);
00183 }
00184 }
00185 } else {
00186 PlaceFormToStack(form, 0);
00187 }
00188 #if 0 // INTELIB_CONTINUATION_KEEPS_STACK_INFO == 1
00189 todo_stack[keepstack_position].stack_info = SReference(*form);
00190 #endif
00191 }
00192
00193 SReference& SchemeContinuation::GetSymbolValue(SchExpressionSymbol *sym) const
00194 {
00195 SReference *lexval = 0;
00196 if(GetContext().GetPtr()) {
00197 lexval = GetContext()->GetBinding(sym);
00198 }
00199 if(lexval)
00200 return *lexval;
00201 else
00202 return sym->GetGlobalValue();
00203 }
00204
00205 #if 0
00206 IntelibX_scheme_not_a_function::
00207 IntelibX_scheme_not_a_function(SReference a_param)
00208 : IntelibX("scheme: not a function", a_param) {}
00209 #endif
00210
00211 IntelibX_scheme_not_a_context::
00212 IntelibX_scheme_not_a_context(SReference a_param)
00213 : IntelibX("scheme: not a context", a_param) {}
00214
00215 IntelibX_scheme_symbol_has_no_value::
00216 IntelibX_scheme_symbol_has_no_value(SReference a_param)
00217 : IntelibX("scheme: symbol has no value", a_param) {}
00218