// -*- mode:C++; tab-width:2; c-basic-offset:2; indent-tabs-mode:nil -*-
//
// Copyright (C) 2000-2005 by Roger Rene Kommer / artefaktur, Kassel, Germany.
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU Library General Public License (LGPL).
//
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// License ACDK-FreeLicense document enclosed in the distribution
// for more for more details.
// This file is part of the Artefaktur Component Development Kit:
// ACDK
//
// Please refer to
// - http://www.acdk.de
// - http://www.artefaktur.com
// - http://acdk.sourceforge.net
// for more information.
//
// $Header: /cvsroot/acdk/acdk/acdk_lisp/src/acdk/lisp/LispEnvironment.cpp,v 1.33 2005/04/29 08:28:06 kommer Exp $
#include <acdk.h>
#include <acdk/lang/Error.h>
#include <acdk/lang/Integer.h>
#include <acdk/lang/System.h>
#include <acdk/io/File.h>
#include <acdk/io/MemReader.h>
#include <acdk/io/StringReader.h>
#include <acdk/io/ByteToCharReader.h>
#include <acdk/util/Properties.h>
#include <acdk/util/HashMap.h>
#include <acdk/util/HashSet.h>
#include <acdk/util/Iterator.h>
#include <acdk/util/DoubleIterator.h>
#include <acdk/locale/Encoding.h>
#include <acdk/util/logging/Log.h>
#include "lisp.h"
#include "LispEnvironment.h"
#include "LispTokenizer.h"
#include "LispException.h"
#include "LispObject.h"
#include "LispBuildInFunction.h"
namespace acdk {
namespace lisp {
using namespace acdk::lang;
using namespace acdk::io;
//using namespace acdk::util;
using acdk::util::RIterator;
using acdk::util::HashMap;
using acdk::util::HashSet;
using acdk::util::RProperties;
//static
LispEnvironment* LispEnvironment::_lenv = 0;
//static
RLispEnvironment LispEnvironment::_glenv;
RLispVar
LispBuildInFunction::eval(IN(RLispEnvironment) env, IN(RLispList) args)
{
return _function->eval(env, args);
}
//virtual
acdk::lang::Object
LispArray::clone(sys::Allocator* alc)
{
//### not implemented yet
//return new LispArray(this);
return Nil;
}
void
dumpStackFrame(IN(RHashMap) cf, IN(RCharWriter) out)
{
RIterator it = cf->keySet()->iterator();
while (it->hasNext() == true) {
RString str = (RString)it->next();
RLispVar val = (RLispVar)cf->get((acdk::lang::Object)str);
RString tstr = str + "=[" + (val == Nil ? RString("Nil") : val->toCode()) + "]\n";
out->writeString(tstr);
out->flush();
}
}
void
getDumpedStackFrame(IN(RHashMap) cf, StringBuffer& sb)
{
RIterator it = cf->keySet()->iterator();
while (it->hasNext() == true) {
RString str = (RString)it->next();
RLispVar val = (RLispVar)cf->get((acdk::lang::Object)str);
sb.append(str);
sb.append("=[");
str = (val == Nil ? RString("Nil") : val->toCode());
sb.append(str);
sb.append("]\n");
}
}
void
getDumpedEnv(IN(acdk::util::RProperties) cf, StringBuffer& sb)
{
RIterator it = cf->keySet()->iterator();
while (it->hasNext() == true) {
RString str = (RString)it->next();
RString val = cf->getProperty(str);
sb.append(str);
sb.append("=[");
sb.append(val);
sb.append("]\n");
}
}
RString
LispStackFrame::toString()
{
StringBuffer sb(1024);
getDumpedStackFrame(_current, sb);
if (_parent != Nil) {
sb.append("parent stack frame:\n");
sb.append(_parent->toString());
}
return sb.toString();
}
acdk::util::RIterator
LispEnvironment::functionIterator()
{
return new acdk::util::DoubleIterator(_staticFuncs()->keySet()->iterator(), _defuns->keySet()->iterator());
}
acdk::util::RIterator
LispEnvironment::buildinsIterator()
{
return _staticFuncs()->keySet()->iterator();
}
acdk::util::RIterator
LispEnvironment::defunsIterator()
{
return _defuns->keySet()->iterator();
}
//static
RHashMap LispEnvironment::__staticFuncs; // RString=RNativeFunc
void
LispEnvironment::registerDefun(IN(RLispFunction) func)
{
_defuns->put((acdk::lang::Object)func->name(), (acdk::lang::Object)func);
}
RLispVar lisp_plus(IN(RLispEnvironment) env, IN(RLispList) args);
RLispVar lisp_minus(IN(RLispEnvironment) env, IN(RLispList) args);
RLispVar lisp_multiply(IN(RLispEnvironment) env, IN(RLispList) args);
RLispVar lisp_divide(IN(RLispEnvironment) env, IN(RLispList) args);
RLispVar lisp_modulo(IN(RLispEnvironment) env, IN(RLispList) args);
RLispVar lisp_gt(IN(RLispEnvironment) env, IN(RLispList) args);
RLispVar lisp_listp(IN(RLispEnvironment) env, IN(RLispList) args);
RLispVar lisp_not(IN(RLispEnvironment) env, IN(RLispList) args);
RLispVar lisp_and(IN(RLispEnvironment) env, IN(RLispList) args);
RLispVar lisp_or(IN(RLispEnvironment) env, IN(RLispList) args);
RLispVar lisp_eq(IN(RLispEnvironment) env, IN(RLispList) ags);
RLispVar lisp_eql(IN(RLispEnvironment) env, IN(RLispList) args);
RLispVar lisp_eql(IN(RLispEnvironment) env, IN(RLispList) args);
RLispVar lisp_length(IN(RLispEnvironment) env, IN(RLispList) args);
RLispVar lisp_quote(IN(RLispEnvironment) env, IN(RLispList) args);
RLispVar lisp_backquote(IN(RLispEnvironment) env, IN(RLispList) args);
RLispVar lisp_comma(IN(RLispEnvironment) env, IN(RLispList) args);
RLispVar lisp_commaat(IN(RLispEnvironment) env, IN(RLispList) args);
RLispVar lisp_list(IN(RLispEnvironment) env, IN(RLispList) args);
RLispVar lisp_append(IN(RLispEnvironment) env, IN(RLispList) args);
RLispVar lisp_setnth(IN(RLispEnvironment) env, IN(RLispList) args);
RLispVar lisp_cons(IN(RLispEnvironment) env, IN(RLispList) args);
RLispVar lisp_car(IN(RLispEnvironment) env, IN(RLispList) args);
RLispVar lisp_cdr(IN(RLispEnvironment) env, IN(RLispList) args);
RLispVar lisp_eval(IN(RLispEnvironment) env, IN(RLispList) args);
RLispVar lisp_let(IN(RLispEnvironment) env, IN(RLispList) args);
RLispVar lisp_unpack(IN(RLispEnvironment) env, IN(RLispList) args);
RLispVar lisp_lambda(IN(RLispEnvironment) env, IN(RLispList) args);
RLispVar lisp_defun(IN(RLispEnvironment) env, IN(RLispList) args);
RLispVar lisp_defmacro(IN(RLispEnvironment) env, IN(RLispList) args);
RLispVar lisp_defclass(IN(RLispEnvironment) env, IN(RLispList) args);
RLispVar lisp_make_instance(IN(RLispEnvironment) env, IN(RLispList) args);
RLispVar lisp_progn(IN(RLispEnvironment) env, IN(RLispList) args);
RLispVar lisp_apply(IN(RLispEnvironment) env, IN(RLispList) args);
RLispVar lisp_if(IN(RLispEnvironment) env, IN(RLispList) args);
RLispVar lisp_cond(IN(RLispEnvironment) env, IN(RLispList) args);
RLispVar lisp_while(IN(RLispEnvironment) env, IN(RLispList) args);
RLispVar lisp_do(IN(RLispEnvironment) env, IN(RLispList) args);
RLispVar lisp_dolist(IN(RLispEnvironment) env, IN(RLispList) args);
RLispVar lisp_return(IN(RLispEnvironment) env, IN(RLispList) args);
RLispVar lisp_getv(IN(RLispEnvironment) env, IN(RLispList) args);
RLispVar lisp_setv(IN(RLispEnvironment) env, IN(RLispList) args);
RLispVar lisp_setq(IN(RLispEnvironment) env, IN(RLispList) args);
RLispVar lisp_setf(IN(RLispEnvironment) env, IN(RLispList) args);
RLispVar lisp_define(IN(RLispEnvironment) env, IN(RLispList) args);
RLispVar lisp_invoke(IN(RLispEnvironment) env, IN(RLispList) args);
RLispVar lisp_invoke_static(IN(RLispEnvironment) env, IN(RLispList) args);
RLispVar lisp_new(IN(RLispEnvironment) env, IN(RLispList) args);
RLispVar lisp_peek(IN(RLispEnvironment) env, IN(RLispList) args);
RLispVar lisp_peek_static(IN(RLispEnvironment) env, IN(RLispList) args);
RLispVar lisp_poke(IN(RLispEnvironment) env, IN(RLispList) args);
RLispVar lisp_poke_static(IN(RLispEnvironment) env, IN(RLispList) args);
RLispVar lisp_try(IN(RLispEnvironment) env, IN(RLispList) args);
RLispVar lisp_throw(IN(RLispEnvironment) env, IN(RLispList) args);
RLispVar lisp_dump(IN(RLispEnvironment) env, IN(RLispList) args);
RLispVar lisp_zerop(IN(RLispEnvironment) env, IN(RLispList) args);
RLispVar lisp_truep(IN(RLispEnvironment) env, IN(RLispList) args);
RLispVar lisp_listp(IN(RLispEnvironment) env, IN(RLispList) args);
RLispVar lisp_atomp(IN(RLispEnvironment) env, IN(RLispList) args);
RLispVar lisp_symbolp(IN(RLispEnvironment) env, IN(RLispList) args);
RLispVar lisp_trace(IN(RLispEnvironment) env, IN(RLispList) args);
RLispVar lisp_instanceof(IN(RLispEnvironment) env, IN(RLispList) args);
RLispVar lisp_isdef(IN(RLispEnvironment) env, IN(RLispList) args);
RLispVar lisp_internal(IN(RLispEnvironment) env, IN(RLispList) args);
RLispVar lisp_internalp(IN(RLispEnvironment) env, IN(RLispList) args);
RLispVar lisp_acdk_lisp_include(IN(RLispEnvironment) env, IN(RLispList) args);
RLispVar lisp_explore(IN(RLispEnvironment) env, IN(RLispList) args);
RLispVar lisp_dp(IN(RLispEnvironment) env, IN(RLispList) args);
RLispVar lisp_create_array(IN(RLispEnvironment) env, IN(RLispList) args);
RLispVar lisp_number_equal(IN(RLispEnvironment) env, IN(RLispList) args);
//static
void
LispEnvironment::registerFunction(const char* name, const char* decl, LispNativFunction func, bool preeval)
{
RHashMap sf = _staticFuncs();
RString str = name;
sf->put(&str, new LispCallBack(decl, func, preeval));
}
//static
RHashMap
LispEnvironment::_staticFuncs()
{
if (__staticFuncs != Nil)
return __staticFuncs;
__staticFuncs = new HashMap();
__staticFuncs->put((acdk::lang::Object)(RString)"zerop",
new LispCallBack("(defun zerop (val) \"return t if giben [val] is Nil\")", lisp_zerop, true));
__staticFuncs->put((acdk::lang::Object)(RString)"truep",
new LispCallBack("(defun truep (val) \"return t if given [val] is a reference to t\")", lisp_truep, true));
__staticFuncs->put((acdk::lang::Object)(RString)"atomp",
new LispCallBack("(defun atomp (val) \"return t if giben [val] is an atom\")", lisp_atomp, true));
__staticFuncs->put((acdk::lang::Object)(RString)"listp", new LispCallBack("(defun listp (val) \"return t if giben [val] is an list\")", lisp_listp, true));
__staticFuncs->put((acdk::lang::Object)(RString)"symbolp", new LispCallBack("(defun symbolp (val) \"return t if giben [val] is a symbol\")", lisp_symbolp, true));
__staticFuncs->put((acdk::lang::Object)(RString)"instanceof",
new LispCallBack(
"(defun instanceof (object classtype)"
"\"(instanceof object 'classtype) or (instanceof object 'classname)\\n"
"return t if given instance of [object] is type of [classtype], otherwise Nil\""
")"
, lisp_instanceof, true));
__staticFuncs->put((acdk::lang::Object)(RString)"trace",
new LispCallBack(
"(defun trace (onoff)"
"\"(trace [0|1])\\n"
"trace 1 print eval on out\""
")"
, lisp_trace, true));
__staticFuncs->put((acdk::lang::Object)(RString)"dump", new LispCallBack(
"(defun dump (&rest args) \"special args:\n"
"\t'sf[level] level optional or x for all frames\tStack Frame\n"
"\t'cs[level]\tcall stack\n\t'globals\tglobal varariables\n\t'env\tenvironment variables\n\tdefuns\tfunctions defintion\")", lisp_dump, true));
__staticFuncs->put((acdk::lang::Object)(RString)"lambda", new LispCallBack("(defun lambda (&rest args) \"define a new function\")", lisp_lambda, false));
__staticFuncs->put((acdk::lang::Object)(RString)"defun", new LispCallBack("(defun defun (&rest args) \"define a new function\")", lisp_defun, false));
__staticFuncs->put((acdk::lang::Object)(RString)"progn", new LispCallBack("(defun progn (&rest args)) \"to define a block.\nAll args will be evaluated, the result is the result of the last arg\"", lisp_progn, false));
__staticFuncs->put((acdk::lang::Object)(RString)"apply", new LispCallBack("(defun apply (&rest args))", lisp_apply, true));
__staticFuncs->put((acdk::lang::Object)(RString)"defmacro", new LispCallBack("(defun defmacro (&rest args) \"not implemented yet\")", lisp_defmacro, false));
__staticFuncs->put((acdk::lang::Object)(RString)"defclass", new LispCallBack("(defun defclass (&rest args) \"implements a object class\")", lisp_defclass, false));
__staticFuncs->put((acdk::lang::Object)(RString)"make-instance", new LispCallBack("(defun make-instance (classname &rest args) \"creates an CLOS object instance\")", lisp_make_instance, false));
__staticFuncs->put((acdk::lang::Object)(RString)"+", new LispCallBack("(defun + (first &rest args))", lisp_plus));
__staticFuncs->put((acdk::lang::Object)(RString)"-", new LispCallBack("(defun - (first second))", lisp_minus));
__staticFuncs->put((acdk::lang::Object)(RString)"*", new LispCallBack("(defun * (first &rest args))", lisp_multiply));
__staticFuncs->put((acdk::lang::Object)(RString)">", new LispCallBack("(defun > (first second))", lisp_gt));
__staticFuncs->put((acdk::lang::Object)(RString)"/", new LispCallBack("(defun / (first second))", lisp_divide));
__staticFuncs->put((acdk::lang::Object)(RString)"%", new LispCallBack("(defun % (first second))", lisp_modulo));
__staticFuncs->put((acdk::lang::Object)(RString)"not", new LispCallBack("(defun not (expr))", lisp_not));
__staticFuncs->put((acdk::lang::Object)(RString)"and", new LispCallBack("(defun and (first &rest args))", lisp_and, false));
__staticFuncs->put((acdk::lang::Object)(RString)"or", new LispCallBack("(defun or (first &rest args))", lisp_or, false));
__staticFuncs->put((acdk::lang::Object)(RString)"eq", new LispCallBack("(defun eq (first second))", lisp_eq));
__staticFuncs->put((acdk::lang::Object)(RString)"eql", new LispCallBack("(defun eql (first second))", lisp_eql));
__staticFuncs->put((acdk::lang::Object)(RString)"equal", new LispCallBack("(defun equal (first second))", lisp_eql));
__staticFuncs->put((acdk::lang::Object)(RString)"length", new LispCallBack("(defun length (list))", lisp_length));
__staticFuncs->put((acdk::lang::Object)(RString)"quote", new LispCallBack("(defun quote (arg))", lisp_quote, false));
__staticFuncs->put((acdk::lang::Object)(RString)"backquote", new LispCallBack("(defmacro backquote (arg))", lisp_backquote, false));
__staticFuncs->put((acdk::lang::Object)(RString)"comma", new LispCallBack("(defmacro comma (arg))", lisp_comma, false, false));
__staticFuncs->put((acdk::lang::Object)(RString)"commaat", new LispCallBack("(defmacro commaat (arg))", lisp_commaat, false, false));
__staticFuncs->put((acdk::lang::Object)(RString)"list", new LispCallBack("(defun list (&rest elements))", lisp_list, true));
__staticFuncs->put((acdk::lang::Object)(RString)"append", new LispCallBack("(defun append (list element))", lisp_append, true));
__staticFuncs->put((acdk::lang::Object)(RString)"setnth", new LispCallBack("(defun setnth (list idx element))", lisp_setnth, true));
__staticFuncs->put((acdk::lang::Object)(RString)"cons", new LispCallBack("(defun cons (list el))", lisp_cons, true));
__staticFuncs->put((acdk::lang::Object)(RString)"car", new LispCallBack("(defun car (list))", lisp_car, true));
__staticFuncs->put((acdk::lang::Object)(RString)"cdr", new LispCallBack("(defun cdr (list))", lisp_cdr, true));
__staticFuncs->put((acdk::lang::Object)(RString)"eval", new LispCallBack("(defun eval (expr))", lisp_eval, true));
__staticFuncs->put((acdk::lang::Object)(RString)"=", new LispCallBack("(defun = (first second))", lisp_number_equal, true));
__staticFuncs->put((acdk::lang::Object)(RString)"unpack", new LispCallBack("(defun unpack (var) \"In case <var> contains LispVar it will return it\")", lisp_unpack, true));
__staticFuncs->put((acdk::lang::Object)(RString)"getv", new LispCallBack("(defun getv (varname value))", lisp_getv, false));
__staticFuncs->put((acdk::lang::Object)(RString)"setv", new LispCallBack("(defun setv (varname value))", lisp_setv, false));
__staticFuncs->put((acdk::lang::Object)(RString)"setq", new LispCallBack("(defun setq (symbol value))", lisp_setq, false));
__staticFuncs->put((acdk::lang::Object)(RString)"setg", new LispCallBack("(defun setg (symbol value))", lisp_setq, false));
__staticFuncs->put((acdk::lang::Object)(RString)"setf", new LispCallBack("(defun setf (symbol value))", lisp_setf, false));
__staticFuncs->put((acdk::lang::Object)(RString)"set", new LispCallBack("(defun set (symbol value))", lisp_setf, false));
__staticFuncs->put((acdk::lang::Object)(RString)"let", new LispCallBack("(defun let (&rest args))", lisp_let, false));
__staticFuncs->put((acdk::lang::Object)(RString)"if", new LispCallBack("(defmacro if (cond expr1 &optional expr2))", lisp_if, false));
__staticFuncs->put((acdk::lang::Object)(RString)"cond", new LispCallBack("(defmacro cond (&rest condblocks) \"see lisp manual\")", lisp_cond, false));
__staticFuncs->put((acdk::lang::Object)(RString)"while", new LispCallBack("(defmacro while (cond expr))", lisp_while, false));
__staticFuncs->put((acdk::lang::Object)(RString)"dolist", new LispCallBack("(defmacro dolist ((element list erg) body1 &rest bodyn))", lisp_dolist, false));
__staticFuncs->put((acdk::lang::Object)(RString)"do", new LispCallBack("(defmacro do (&rest args))", lisp_do, false));
__staticFuncs->put((acdk::lang::Object)(RString)"return", new LispCallBack("(defun return (&optional retvalue))", lisp_return, true));
__staticFuncs->put((acdk::lang::Object)(RString)"explore", new LispCallBack("(defun explore (object))", lisp_explore, true));
__staticFuncs->put((acdk::lang::Object)(RString)"dp", new LispCallBack("(defun dp (&optional value))", lisp_dp, true));
__staticFuncs->put((acdk::lang::Object)(RString)"create-array", new LispCallBack("(defun create-array (size))", lisp_create_array, true));
__staticFuncs->put((acdk::lang::Object)(RString)"isdef", new LispCallBack("(defmacro isdef (symbol) \"return true if given symbol can be found in symbol table\")", lisp_isdef, false));
__staticFuncs->put((acdk::lang::Object)(RString)"internal", new LispCallBack("(defmacro internal (symbol) \"returns the internal representation of symbol\")", lisp_internal, false));
__staticFuncs->put((acdk::lang::Object)(RString)"internalp", new LispCallBack("(defmacro internalp (symbol) \"returns the internal representation of the object symbol points to\")", lisp_internalp, false));
// while
// apply
__staticFuncs->put((acdk::lang::Object)(RString)"new", new LispCallBack("(defun new (classymbol &rest constructorargs))", lisp_new, true));
__staticFuncs->put((acdk::lang::Object)(RString)"invoke", new LispCallBack("(defun invoke (object method, &rest methodargs))", lisp_invoke, true));
__staticFuncs->put((acdk::lang::Object)(RString)"invoke-static", new LispCallBack("(defun invoke-static (classymbol method, &rest methodargs))", lisp_invoke_static, true));
__staticFuncs->put((acdk::lang::Object)(RString)"peek", new LispCallBack("(defun peek (object membername)"
"\"reads a public member variable of a ACDK object\")", lisp_peek, true));
__staticFuncs->put((acdk::lang::Object)(RString)"peek-static", new LispCallBack("(defun peek-static (classymbol membername)"
"\"reads a static public member variable of the given ACDK class\")", lisp_peek_static, true));
__staticFuncs->put((acdk::lang::Object)(RString)"poke", new LispCallBack("(defun poke (object membername value)"
"\"writes a given value to the ACDK object public member\")", lisp_poke, true));
__staticFuncs->put((acdk::lang::Object)(RString)"poke-static", new LispCallBack("(defun poke-static (classymbol membername value)"
"\"writes a static public member variable of the given ACDK class\")", lisp_poke_static, true));
__staticFuncs->put((acdk::lang::Object)(RString)"try", new LispCallBack("(defmacro try (&rest body))", lisp_try, false));
__staticFuncs->put((acdk::lang::Object)(RString)"throw", new LispCallBack("(defmacro throw (exceptionsymbol &rest exargs))", lisp_throw, true));
__staticFuncs->put((acdk::lang::Object)(RString)"include", new LispCallBack("(defmacro include (filename))", lisp_acdk_lisp_include, true));
return __staticFuncs;
}
//static
//RLispNil LispEnvironment::__nil;
//static
RLispAtom LispEnvironment::__trueVar; // true
/*
//static
RLispNil
LispEnvironment::nil()
{
if (__nil != Nil)
return __nil;
__nil = new LispNil();
System::registerStaticReference(__nil);
return __nil;
}
*/
//static
RLispAtom
LispEnvironment::t()
{
if (__trueVar != Nil)
return __trueVar;
__trueVar = new LispAtom(RString("TRUE"));
System::registerStaticReference(__trueVar);
return __trueVar;
}
void
LispEnvironment::initEnv()
{
if (_environment->getProperty("*thisfile*") == Nil)
_environment->setProperty("*thisfile*", RString("NIL"));
_stackFrame.push(new LispStackFrame()); // for interaction
RLispVar e = new LispAtom(ScriptVar(acdk::lang::Object(this)));
bindGlobal("*env*", e);
bindGlobal("env", e);
bindLocal("env", e);
RLispAtom temp = new LispAtom(ScriptVar(acdk::lang::Object(_cmlineArgs)));
bindGlobal("*args*", RLispVar(temp));
bindGlobal("args", RLispVar(temp));
bindLocal("args", RLispVar(temp));
bindGlobal("t", (RLispVar)t());
bindLocal("T", (RLispVar)t());
if (_environment->getProperty("*interactive*") == Nil)
_environment->setProperty("*interactive*", RString("NIL"));
}
LispEnvironment::LispEnvironment(IN(RProperties) environment, IN(RStringArray) args, bool trace)
: acdk::lang::Object(),
_environment(environment),
_globals(new HashMap()),
_defuns(new HashMap()),
_includes(new HashSet()),
_tracedSymbols(new HashSet()),
_trace(trace),
_returnNow(false),
_tracelevel(0),
_break(0),
_exitNow(false),
_exitValue(0),
_cmlineArgs(args),
out(System::out),
err(System::err),
in(System::in)
{
ACDK_SAFE_CONSTRUCTOR(); // to prevent delete this
_lenv = this;
if (_environment == Nil)
_environment = System::getProperties();
}
LispEnvironment::~LispEnvironment()
{
_lenv = 0;
}
void
LispEnvironment::init(bool loadCode)
{
if (_environment->getProperty("ACDK_TOOLS_HOME") == Nil && _environment->getProperty("ACDKHOME") == Nil)
THROW1(Error, "environment variable ACDKHOME or ACDK_TOOLS_HOME must be set as env-var or with -acdk-[tools-]home=[dir] as command line flag ");
RString acdkhome = _environment->getProperty("ACDK_TOOLS_HOME");
if (acdkhome == Nil)
acdkhome = _environment->getProperty("ACDKHOME");
if (loadCode == false)
{
RFile initimg = new File(acdkhome, "cfg/lib/acdk/lisp/autoload.limg");
if (initimg->exists() == false)
{
System::out->println(initimg->getCanonicalPath() + " does not exists. Compile it");
initEnv();
setInOut(&System::in, &System::out, &System::err);
RFile loadingfile = new File(acdkhome, "cfg/lib/acdk/lisp/autoload.lsp");
load(loadingfile->getCanonicalPath());
storeCompiled(initimg->getCanonicalPath());
}
if (initimg->exists() == false)
{
// ### error
}
RPrintWriter sicprintwriter = System::out;
RWriter sicwriter = sicprintwriter->getWriter();
System::out->println("Load image: " + initimg->getName());
loadCompiled(initimg->getReader(), true);
/*
if (sicprintwriter != System::out || sicwriter != System::out->getWriter())
std::cout << "oops" << std::endl;
*/
initEnv();
setInOut(&System::in, &System::out, &System::err);
/*
if (sicprintwriter != System::out || sicwriter != System::out)
std::cout << "oops" << std::endl;
*/
System::out->println("init finished");
} else {
initEnv();
setInOut(&System::in, &System::out, &System::err);
RFile loadingfile = new File(acdkhome, "cfg/lib/acdk/lisp/autoload.lsp");
load(loadingfile->getCanonicalPath());
}
}
void
LispEnvironment::deinit()
{
bindGlobal("*env*", RLispVar(Nil));
bindGlobal("env", RLispVar(Nil));
bindLocal("env", RLispVar(Nil));
__staticFuncs = Nil;
__trueVar = Nil;
}
void
LispEnvironment::traceln(IN(RString) str)
{
System::out->println(str);
out->println(str);
}
void
LispEnvironment::traceflush(IN(RString) str)
{
out->print(str);
out->flush();
}
void
LispEnvironment::trace_begin(IN(RString) str)
{
++_tracelevel;
StringBuffer sb;
for (int i = 0; i < _tracelevel; i++)
sb << " ";
sb << str;
ACDK_NLOG("acdk.lisp.LispEnvironment", Trace, sb.toString());
//out->println(str);
}
void
LispEnvironment::trace_end(IN(RString) str)
{
StringBuffer sb;
for (int i = 0; i < _tracelevel; i++)
sb << " ";
sb << str;
ACDK_NLOG("acdk.lisp.LispEnvironment", Trace, sb.toString());
--_tracelevel;
}
RLispVar
LispEnvironment::debug_interactive(IN(RLispVar) var)
{
LispTokenizer lisptokenizer((::acdk::io::RCharReader)in);
RLispVar erg;
while (exitNow() == false)
{
try {
out->print("[" + (var == Nil ? RString("NIL") : var->toCode()) + "] >");
out->flush();
RLispCode tcode = parse(SR(LispTokenizer, lisptokenizer), out, true);
if (tcode == Nil)
continue;
RLispList code = tcode->code();
RString cod = code->car()->toCode();
if (cod->equals((acdk::lang::Object)(RString)"s") == true || cod->equals((acdk::lang::Object)(RString)"step") == true) {
erg = _eval(var);
out->println("> to [" + (erg == Nil ? RString("NIL") : erg->toCode()) + "]");
return erg;
} else if (cod->equals((acdk::lang::Object)(RString)"n") == true || cod->equals((acdk::lang::Object)(RString)"next") == true) {
int oldbreak = _break;
_break = 0;
erg = eval(var);
_break = oldbreak;
out->println("> to [" + (erg == Nil ? RString("NIL") : erg->toCode()) + "]");
return erg;
} if (cod->equals((acdk::lang::Object)(RString)"c") == true || cod->equals((acdk::lang::Object)(RString)"continue") == true) {
_break = 0;
return eval(var);
} else if (cod->equals((acdk::lang::Object)(RString)"?") == true || cod->equals((acdk::lang::Object)(RString)"h") == true || cod->equals((acdk::lang::Object)(RString)"help") == true) {
out->println("Commands in debug mode:");
out->println("\t?\tprint this help");
out->println("\tn\tnext line");
out->println("\ts\tstep into command");
out->println("\tc\tcontinue");
out->println("\tsee also (dump)");
continue;
}
int oldbreak = _break;
_break = 0;
RLispVar erg;
while (code != Nil) {
StackHolder<RLispVar> __evalStackHolder(_evalStack, code->car());
RString thecode = code->car()->toCode();
erg = eval(code->car());
code = code->cdr();
if (_returnNow == true || exitNow() == true) {
_returnNow = false;
return erg;
}
}
RString tstr = (erg == Nil ? RString("NIL") : erg->toCode());
out->println(tstr);
_break = oldbreak;
} catch (RLispException lex) {
lex->printStackTrace(err);
err->println(lex->getMessage());
setBreak(1);
} catch (RThrowable ex) {
ex->printStackTrace(err);
err->println(ex->getMessage());
setBreak(1);
}
}
return erg;
}
#define REvalCatchException RLispException
RLispVar
LispEnvironment::eval(IN(RLispVar) var)
{
StackHolder<RLispVar> __stack(_evalStack, var);
try {
if (exitNow() == true)
return Nil;
if (trace() == false && getBreak() <= 0) {
_lastEvaled = _eval(var);
#if 0
if ((var == Nil) && (_lastEvaled == Nil))
System::err->println(RString("Evaluated NIL to NIL"));
else if (var == Nil)
System::err->println(RString("Evaluated NIL to ") + _lastEvaled->getName() + "::" + _lastEvaled->toString());
else if (_lastEvaled == Nil)
System::err->println(RString("Evaluated ") + var->getName() + "::" + var->toString() + " to NIL");
else
System::err->println(RString("Evaluated ") + var->getName() + "::" + var->toString() + " to " + _lastEvaled->getName() + "::" + _lastEvaled->toString());
#endif
/FONT>
return _lastEvaled;
}
if (getBreak() > 0)
return debug_interactive(var);
if (var == Nil)
trace_begin("Evaluated [NIL] ");
else
trace_begin("Evaluated [" + var->getName() + "::" + var->toCode() + "] ");
_lastEvaled = _eval(var);
if (_lastEvaled == Nil)
trace_end("to [NIL]");
else
trace_end("to [" + _lastEvaled->getName() + "::" + _lastEvaled->toCode() + "]");
return _lastEvaled;
} catch (RThrowable lex) {
lex->printStackTrace(System::err);
System::err->println(lex->getMessage());
return debug_interactive(var);
}
}
RLispVar
LispEnvironment::_eval(IN(RLispVar) var)
{
if (var == Nil)
return Nil;
if (instanceof(var, LispSymbol) == true)
return _eval((RLispSymbol)var);
else if (instanceof(var, LispAtom) == true)
return _eval((RLispAtom)var);
else if (instanceof(var, LispList) == true)
return _eval((RLispList)var);
else if (instanceof(var, LispBuildInFunction) == true)
return var;
else if (instanceof(var, LispObject) == true)
return var;
else if (instanceof(var, LispClass) == true)
return var;
else
THROW2(LispException, this, "Unknown ListVar type: " + var->toCode());
return Nil;
}
RLispVar quote_invoke()
{
static RLispVar qi = new LispSymbol("invoke");
return qi;
}
RLispVar
LispEnvironment::_eval(IN(RLispList) list)
{
if (list->length() == 0)
return Nil;
RLispVar funcvar = list->car();
/*
#ifdef ACDK_DEBUG
RString tcode = list->toCode();
#endif //ACDK_DEBUG
*/
if (funcvar == Nil)
THROW2(LispException, this, "function is NIL in [" + list->toCode() + "]");
if (funcvar == t())
return funcvar;
if (instanceof(funcvar, LispList) == true)
funcvar = _eval(RLispList(funcvar));
if (instanceof(funcvar, Function) == true)
return RFunction(funcvar)->eval(this, list);
RString tstr = funcvar->toString();
RFunction func = lookupFunction(funcvar->toString());
if (func != Nil)
return func->eval(this, list);
RLispVar var = lookupVar(funcvar->toString());
if (var == Nil)
THROW2(LispException, this, "cannot find function or var: [" + funcvar->toCode() + "] in [" + list->toCode() + "]");
if (instanceof(var, Function) == true)
return RFunction(var)->eval(this, list);
if (instanceof(var, LispAtom) == true)
{
RString lcode = list->toCode();
RLispVar name = list->cdr()->car();
RString membername = name->getStringToken();
if (membername != Nil)
{
return _eval(list->unshift(quote_invoke()));
}
RString ncode = name->toCode();
}
THROW2(LispException, this, "var is not function type: [" + funcvar->toCode() + "] in [" + list->toCode() + "]");
return Nil;
}
RLispVar
LispEnvironment::_eval(IN(RLispSymbol) var)
{
RLispVar erg = lookupVar(var->toString());
if (erg == Nil)
return Nil;
//System::err->println(RString("_eval(") + var->toString() + "): " + erg->toString());
if (instanceof(erg, LispAtom) == true) {
RLispAtom atom = (RLispAtom)erg;
if (atom->val().type == ScriptVar::ObjectType)
if (atom->getObject() == Nil)
return Nil;
}
return erg;
}
RLispVar
LispEnvironment::_eval(IN(RLispAtom) var)
{
return &var; //->toString();
}
//static
RLispList
LispEnvironment::parseToList(IN(RString) str)
{
StringReader strreader(str);
LispTokenizer in(&strreader);
int openbrackets = 0;
Stack<RLispCode> listStack;
listStack.push(new LispCode()); // contains result list
int tk;
while ((tk = in.nextToken()) != StreamTokenizer::TT_EOF) {
if (tk == '(') {
listStack.push(new LispCode());
} else if (tk == ')') {
RLispList ll = listStack.pop()->code();
if (ll == Nil)
ll = new LispList();
listStack.top()->append((RLispVar)ll);
} else if (tk == StreamTokenizer::TT_WORD) {
if (in.sval->equals("NIL") ||
in.sval->equals("nil") == 0 ||
in.sval->equals("Nil") == 0)
listStack.top()->append(Nil);
else
listStack.top()->append(new LispSymbol(in.sval));
} else {
//System::out->println("Unknown token: " + in.sval);
listStack.top()->append(new LispSymbol(in.sval));
}
}
return listStack.top()->code();
}
bool
isInBackQuote(Stack<RLispCode>& listStack)
{
for (int i = listStack.size() - 1; i <= 0; ++i)
{
if (listStack.getFromTop(i)->quotech == '`')
return true;
}
return false;
}
bool quotedSyntax(char quotech)
{
return quotech == '\'' || quotech == '@' || quotech == '`';
}
RLispCode
LispEnvironment::parse(IN(RLispTokenizer) tin, IN(RPrintWriter) tout, bool interactiv/* = false*/, bool parseOneToken/* = false*/)
{
int tk;
Stack<RLispCode> listStack;
listStack.push(new LispCode()); // contains result list
int openbrackets = 0;
bool firstSymbol = false;
try {
bool doBreak = false;
while (doBreak == false && (tk = tin->nextToken()) != StreamTokenizer::TT_EOF) {
if (parseOneToken == true)
doBreak = true;
if (tk == ';') {
THROW0(Exception);
}
// (
if (tk == '(') {
++openbrackets;
listStack.push(new LispCode());
firstSymbol = true;
// )
} else if (tk == ')') {
firstSymbol = false;
--openbrackets;
RLispList ll = listStack.pop()->code();
if (ll == Nil) { // empty list ()
ll = new LispList();
}
RLispVar replaced = ≪
int qch = listStack.top()->quotech;
if (qch == 'M')
{
_eval(ll); // registers Macro
}
else if (qch == 'm')
{
//RString tstr = ll->toCode();
RFunction func = lookupFunction(ll->car()->toString());
if (func == Nil)
; // ### oops
RLispVar erg = func->eval(this, ll);
replaced = erg;
}
listStack.top()->append(replaced);
if (openbrackets == 0 && interactiv == true) {
if (listStack.top()->quotech != 0)
{
listStack.top()->quotech = 0;
RLispList tll = listStack.pop()->code();
if (qch == 'M')
{
RString mcode = tll->toCode();
}
listStack.top()->append((RLispVar)tll);
}
break;
}
// TT_NUMBER
} else if (tk == StreamTokenizer::TT_NUMBER) {
firstSymbol = false;
if (tin->sval->length() == 1 && (tin->sval->equals("-") || tin->sval->equals("+")))
listStack.top()->append(new LispSymbol(tin->sval));
else
listStack.top()->append(new LispAtom(tin->nval->toScriptVar()));
// TT_STRING
} else if (tk == StreamTokenizer::TT_STRING) {
firstSymbol = false;
listStack.top()->append(new LispAtom(tin->sval));
// Symbol TT_WORD
} else if (tk == StreamTokenizer::TT_WORD) {
if (tin->sval->equals("NIL") ||
tin->sval->equals("nil") ||
tin->sval->equals("Nil"))
listStack.top()->append(Nil);
else if (tin->sval->equals("T")||
tin->sval->equalsIgnoreCase("true") == true)
listStack.top()->append((RLispVar)t());
else {
if (firstSymbol == true)
{
if (tin->sval->equals("defmacro") == true)
listStack.getFromTop(2)->quotech = 'M';
else if (isMacro(tin->sval) == true)
listStack.getFromTop(2)->quotech = 'm';
}
listStack.top()->append(new LispSymbol(tin->sval));
}
firstSymbol = false;
// quote
} else if (tk == '\'' || tk == '`') { // quote or backquote
firstSymbol = false;
listStack.push(new LispCode());
if (tk == '\'')
listStack.top()->append(new LispSymbol("quote"));
else
listStack.top()->append(new LispSymbol("backquote"));
listStack.top()->quotech = tk;
continue; // not reach line if (listStack.top()->quoted) {
// comma
} else if (tk == ',' || tk == '@') {
firstSymbol = false;
//if (isInBackQuote(listStack) == false)
// THROW1(ParseException, "Operator , or ,@ are only allowed in backquoted code");
listStack.push(new LispCode());
if (tk == '@')
listStack.top()->append(new LispSymbol("commaat"));
else
listStack.top()->append(new LispSymbol("comma"));
listStack.top()->quotech = tk;
RLispCode slc = parse(tin, tout, interactiv, true);
listStack.top()->append(&slc->code()->car());
listStack.top()->append(&listStack.pop()->code());
continue;
// other
} else {
firstSymbol = false;
if (tk != StreamTokenizer::TT_WORD)
;//System::tout->println("Unknown token: " + tin->sval);
listStack.top()->append(new LispSymbol(tin->sval));
}
if (interactiv == true && listStack.size() == 1)
break;
if (quotedSyntax(listStack.top()->quotech) == true)
{
listStack.top()->quotech = 0;
RLispList ll = listStack.pop()->code();
listStack.top()->append((RLispVar)ll);
}
}
if (tk == StreamTokenizer::TT_EOF)
return listStack.top();
return listStack.top();
} catch (acdk::text::RParseException ex) {
ex->printStackTrace(System::err);
System::err->println(tin->currentLineReference() + ": " + ex->getMessage() + "\n\t: " + tin->currentLine());
return Nil;
}
}
RString
LispEnvironment::load(IN(RLispTokenizer) tok)
{
RLispCode code = parse(tok, System::err);
if (code == Nil || code->code() == Nil)
return Nil;
RLispList codelist = code->code();
//RString tstr = codelist->toCode();
RLispVar erg;
while (codelist != Nil) {
StackHolder<RLispVar> __evalStackHolder(_evalStack, codelist->car());
erg = eval(codelist->car());
if (_returnNow == true) {
_returnNow = false;
break;
}
codelist = codelist->cdr();
}
if (erg == Nil)
return Nil;
return erg->toCode();
}
RString
LispEnvironment::load(IN(RString) filename)
{
try {
RFile file;
RString sav = _environment->getProperty("*thisfile*");
if (File(filename).isAbsolute() == false && _modulStack.empty() == false) {
file = new File(_modulStack.top()->getParentFile(), filename);
} else
file = new File(filename);
_modulStack.push(file);
_environment->setProperty("*thisfile*", file->getCanonicalPath());
RString erg = "";
RFileReader fin = new FileReader(file);
LispTokenizer tok(new ByteToCharReader(&fin, acdk::locale::Encoding::getEncoding("LATIN-1")->getDecoder()));
//while (erg != Nil && tok.eof() == false) // why this loop ??
erg = load(SR(LispTokenizer, tok));
_modulStack.pop();
_environment->setProperty("*thisfile*", (sav == Nil)? RString("NIL") : sav);
return erg;
} catch (RLispException lex) {
lex->printStackTrace(System::err);
System::err->println(lex->getMessage());
setBreak(1);
}
return Nil;
}
/* ###really needed ??
RString
LispEnvironment::parseEval(const char*& ptr, int& rest)
{
//RbyteArray carray = new byteArray((const byte*)ptr, rest);
byteArray ba((const byte*)ptr, rest);
MemReader memreader(&ba);
LispTokenizer tok(&memreader);
if (trace() == true)
trace_begin("Parse [" + memreader.toString() + "]");
RLispCode erg = parse(SR(LispTokenizer, tok), System::err);
if (trace() == true)
trace_end("to [" + erg->code()->toCode() + "]");
RLispVar lerg = eval((RLispVar)erg->code());
return lerg->toCode();
}
*/
RLispVar
LispEnvironment::parseEval(IN(RString) str)
{
StringReader sr(str);
LispTokenizer tok(&sr);
RLispCode erg = parse(&tok, System::err);
// dbg
//RString tstr = erg->code()->toCode();
if (erg == Nil)
return Nil;
RLispList list = erg->code();
RLispVar evaled;
while (list != Nil)
{
evaled = eval(list->car());
list = list->cdr();
}
return evaled;
}
void
LispEnvironment::setInOut(IN(RCharReader) rin, IN(RCharWriter) rout, IN(RCharWriter) rerr)
{
if (instanceof(rin, InputReader))
in = (RInputReader)rin;
else
in = new InputReader(rin);
if (instanceof(rout, PrintWriter))
out = (RPrintWriter)rout;
else
out = new PrintWriter(rout);
if (instanceof(rerr, PrintWriter))
err = (RPrintWriter)rerr;
else
err = new PrintWriter(rerr);
RLispVar o = new LispAtom(ScriptVar((acdk::lang::Object)out));
bindGlobal("out", o);
bindGlobal("*out*", o);
bindGlobal("*out", o);
o = new LispAtom(ScriptVar((acdk::lang::Object)err));
bindGlobal(RString("err"), o);
bindGlobal("*err*", o);
bindGlobal("*err", o);
o = new LispAtom(ScriptVar((acdk::lang::Object)in));
bindGlobal("in", o);
bindGlobal("*in*", o);
bindGlobal("*in", o);
}
void
LispEnvironment::interactive(IN(RCharReader) rin, IN(RCharWriter) rout)
{
setInOut(rin, rout, rout);
RCharReader tin = (RCharReader)in;
while (instanceof(tin, AbstractCharFilterReader) == true)
tin = RAbstractCharFilterReader(tin)->getIn();
LispTokenizer lisptokenizer(tin);
_environment->setProperty("*interactive*", RString("TRUE"));
RLispVar erg;
while (true) {
out->print("> ");
out->flush();
try {
RLispCode tcode = parse(SR(LispTokenizer, lisptokenizer), out, true);
RLispList code = tcode->code();
if (trace() == true)
{
trace_begin("Parsed Code: ");
trace_end("to " + code->toCode());
}
RLispVar erg;
while (code != Nil) {
StackHolder<RLispVar> __evalStackHolder(_evalStack, code->car());
/*
#ifdef ACDK_DEBUG
RString thecode = code->car()->toCode();
#endif //ACDK_DEBUG
*/
erg = eval(code->car());
code = code->cdr();
if (_returnNow == true) {
_returnNow = false;
setInOut(&System::in, &System::out, &System::err);
return;
}
}
RString tstr = (erg == Nil ? RString("NIL") : erg->toCode());
out->println(tstr);
} catch (RLispException lex) {
err->println(lex->getMessage());
setBreak(1);
}
}
}
void
LispEnvironment::bindLocal(IN(RString) symbol, IN(RLispVar) value, bool forcelocal /* = false */)
{
if (trace() == true)
traceln("bindLocal: [ $" + Integer::toString((int)_stackFrame.top().getIPtr()) + "::" + symbol->toString() + "]=[" + (value == Nil ? RString("NIL") : value->toCode()) + "]");
#if 0
if (value == Nil)
System::err->println(RString("bindLocal: ") + "Unknown" + "::" + symbol + " = NIL");
else
System::err->println(RString("bindLocal: ") + value->getName() + "::" + symbol + " = " + value->toString());
#endif
/FONT>
_stackFrame.top()->put(symbol, value, forcelocal);
}
void
LispEnvironment::bindGlobal(IN(RString) symbol, IN(RLispVar) value)
{
if (trace() == true)
traceln("bindGlobal: [" + symbol->toString() + "]=[" + (value == Nil ? RString("NIL") : value->toCode()) + "]");
#if 0
if (value == Nil)
System::err->println(RString("bindGlobal: ") + "Unknown" + "::" + symbol + " = NIL");
else
System::err->println(RString("bindGlobal: ") + value->getName() + "::" + symbol + " = " + value->toString());
#endif
/FONT>
_globals->put((acdk::lang::Object)symbol, (acdk::lang::Object)value);
}
void
LispEnvironment::bindToEnv(IN(RString) symbol, IN(RLispVar) value)
{
if (trace() == true)
traceln("bindEnv: [" + symbol->toString() + "]=[" + (value == Nil ? RString("NIL") : value->toCode()) + "]");
#if 0
if (value == Nil)
System::err->println(RString("bindToEnv: ") + "Unknown" + "::" + symbol + " = NIL");
else
System::err->println(RString("bindToEnv: ") + value->getName() + "::" + symbol + " = " + value->toString());
#endif
/FONT>
RString str = (value == Nil)? RString("NIL") : value->toString();
_environment->put(&symbol, &str);
}
RLispVar
LispEnvironment::lookupVar(IN(RString) symbol, bool warn)
{
RLispVar v;
if (_stackFrame.top()->containsKey(symbol) == true) {
v = (RLispVar)_stackFrame.top()->get(symbol);
#if 0
if (v == Nil)
System::err->println(RString("lookupVar(") + symbol + ") " + RString("local: ") + "NIL");
else
System::err->println(RString("lookupVar(") + symbol + ") " + RString("local: ") + v->getName() + "::" + v->toString());
#endif
/FONT>
return v;
}
RFunction func = lookupFunction(symbol);
if (func != Nil) {
return new LispBuildInFunction(symbol, func);
}
if (_globals->containsKey((acdk::lang::Object)symbol)) {
v = (RLispVar)_globals->get((acdk::lang::Object)symbol);
#if 0
if (v == Nil)
System::err->println(RString("lookupVar(") + symbol + ") " + RString("global: ") + "NIL");
else
System::err->println(RString("lookupVar(") + symbol + ") " + RString("global: ") + v->getName() + "::" + v->toString());
#endif
/FONT>
return v;
}
RString str = _environment->getProperty(symbol);
if (str != Nil) {
if (str->equalsIgnoreCase("TRUE"))
v = (RLispVar)t();
else if (str->equalsIgnoreCase("NIL")) {
v = new LispAtom(ScriptVar(acdk::lang::Object(Nil)));
}
else
v = new LispAtom(str);
#if 0
if (v == Nil)
System::err->println(RString("lookupVar(") + symbol + ") " + RString("env: ") + "NIL");
else
System::err->println(RString("lookupVar(") + symbol + ") " + RString("env: ") + v->getName() + "::" + v->toString());
#endif
/FONT>
return v;
}
#if 0
System::err->println(RString("lookupVar(") + symbol + ") " + RString("undefined"));
#endif
/FONT>
if (symbol->equals("ACDK_TOOLS_HOME") == true)
return new LispAtom(System::getAcdkToolsHome());
if (symbol->equals("ACDKHOME") == true || symbol->equals("ACDK_HOME") == true)
return new LispAtom(System::getAcdkHome());
if (warn == false)
return Nil;
traceln("** WARN: Symbol [" + symbol + "] is not defined");
setBreak(1);
return Nil;
}
RLispVar
LispEnvironment::lookupLocalVar(IN(RString) str)
{
if (_stackFrame.top()->containsKey(str) == false)
return Nil;
return (RLispVar)_stackFrame.top()->get(str);
}
RFunction
LispEnvironment::lookupFunction(IN(RString) str)
{
RFunction func = (RFunction)_staticFuncs()->get((acdk::lang::Object)str);
if (func != Nil)
return func;
func = (RFunction)_defuns->get((acdk::lang::Object)str);
return func;
}
void
dumpStackFrame(IN(RLispStackFrame) cf, IN(RCharWriter) out)
{
RIterator it = cf->keySet()->iterator();
while (it->hasNext() == true)
{
RString str = (RString)it->next();
RLispVar val = (RLispVar)cf->get(str);
RString tstr = str + "=" + (val == Nil ? RString("Nil") : val->toCode()) + "\n";
out->writeString(tstr);
out->flush();
}
}
void
LispEnvironment::dumpEnv(IN(RCharWriter) out)
{
RLispStackFrame cf = _stackFrame.top();
out->writeString("Current Stack:\n");
dumpStackFrame(cf, out);
out->writeString("Globals:\n");
dumpStackFrame(_globals, out);
out->writeString("Defuns:\n");
dumpStackFrame(_defuns, out);
}
RString
LispEnvironment::loadUnparsedFile(IN(RString) filename)
{
File f(filename);
if (f.exists() == false)
return "";
jlong l = f.length();
RcharArray ch = new charArray(l);
FileReader fin(filename);
ByteToCharReader cin(&fin, acdk::locale::Encoding::getEncoding("LATIN-1")->getDecoder());
return cin.readString();
}
} // namespace lisp
} // namespace acdk
|