mirror of
https://github.com/kanaka/mal.git
synced 2024-09-21 18:48:12 +03:00
Merge pull request #132 from sdt/native-swap
Native swap! implementation for cpp
This commit is contained in:
commit
93cba02fb9
21
cpp/Core.cpp
21
cpp/Core.cpp
@ -33,7 +33,7 @@ static StaticList<malBuiltIn*> handlers;
|
||||
static StaticList<malBuiltIn*>::Node HRECNAME(uniq) \
|
||||
(handlers, new malBuiltIn(symbol, FUNCNAME(uniq))); \
|
||||
malValuePtr FUNCNAME(uniq)(const String& name, \
|
||||
malValueIter argsBegin, malValueIter argsEnd, malEnvPtr env)
|
||||
malValueIter argsBegin, malValueIter argsEnd)
|
||||
|
||||
#define BUILTIN(symbol) BUILTIN_DEF(__LINE__, symbol)
|
||||
|
||||
@ -121,7 +121,7 @@ BUILTIN("apply")
|
||||
args.push_back(lastArg->item(i));
|
||||
}
|
||||
|
||||
return APPLY(op, args.begin(), args.end(), env->getRoot());
|
||||
return APPLY(op, args.begin(), args.end());
|
||||
}
|
||||
|
||||
BUILTIN("assoc")
|
||||
@ -227,7 +227,7 @@ BUILTIN("empty?")
|
||||
BUILTIN("eval")
|
||||
{
|
||||
CHECK_ARGS_IS(1);
|
||||
return EVAL(*argsBegin, env->getRoot());
|
||||
return EVAL(*argsBegin, NULL);
|
||||
}
|
||||
|
||||
BUILTIN("first")
|
||||
@ -357,6 +357,21 @@ BUILTIN("str")
|
||||
return mal::string(printValues(argsBegin, argsEnd, "", false));
|
||||
}
|
||||
|
||||
BUILTIN("swap!")
|
||||
{
|
||||
CHECK_ARGS_AT_LEAST(2);
|
||||
ARG(malAtom, atom);
|
||||
|
||||
malValuePtr op = *argsBegin++; // this gets checked in APPLY
|
||||
|
||||
malValueVec args(1 + argsEnd - argsBegin);
|
||||
args[0] = atom->deref();
|
||||
std::copy(argsBegin, argsEnd, args.begin() + 1);
|
||||
|
||||
malValuePtr value = APPLY(op, args.begin(), args.end());
|
||||
return atom->reset(value);
|
||||
}
|
||||
|
||||
BUILTIN("symbol")
|
||||
{
|
||||
CHECK_ARGS_IS(1);
|
||||
|
@ -18,8 +18,7 @@ typedef RefCountedPtr<malEnv> malEnvPtr;
|
||||
|
||||
// step*.cpp
|
||||
extern malValuePtr APPLY(malValuePtr op,
|
||||
malValueIter argsBegin, malValueIter argsEnd,
|
||||
malEnvPtr env);
|
||||
malValueIter argsBegin, malValueIter argsEnd);
|
||||
extern malValuePtr EVAL(malValuePtr ast, malEnvPtr env);
|
||||
extern malValuePtr readline(const String& prompt);
|
||||
extern String rep(const String& input, malEnvPtr env);
|
||||
|
@ -112,10 +112,9 @@ namespace mal {
|
||||
};
|
||||
|
||||
malValuePtr malBuiltIn::apply(malValueIter argsBegin,
|
||||
malValueIter argsEnd,
|
||||
malEnvPtr env) const
|
||||
malValueIter argsEnd) const
|
||||
{
|
||||
return m_handler(m_name, argsBegin, argsEnd, env);
|
||||
return m_handler(m_name, argsBegin, argsEnd);
|
||||
}
|
||||
|
||||
static String makeHashKey(malValuePtr key)
|
||||
@ -302,8 +301,7 @@ malLambda::malLambda(const malLambda& that, bool isMacro)
|
||||
}
|
||||
|
||||
malValuePtr malLambda::apply(malValueIter argsBegin,
|
||||
malValueIter argsEnd,
|
||||
malEnvPtr) const
|
||||
malValueIter argsEnd) const
|
||||
{
|
||||
return EVAL(m_body, makeEnv(argsBegin, argsEnd));
|
||||
}
|
||||
@ -342,7 +340,7 @@ malValuePtr malList::eval(malEnvPtr env)
|
||||
std::unique_ptr<malValueVec> items(evalItems(env));
|
||||
auto it = items->begin();
|
||||
malValuePtr op = *it;
|
||||
return APPLY(op, ++it, items->end(), env);
|
||||
return APPLY(op, ++it, items->end());
|
||||
}
|
||||
|
||||
String malList::print(bool readably) const
|
||||
|
12
cpp/Types.h
12
cpp/Types.h
@ -227,8 +227,7 @@ public:
|
||||
malApplicable(malValuePtr meta) : malValue(meta) { }
|
||||
|
||||
virtual malValuePtr apply(malValueIter argsBegin,
|
||||
malValueIter argsEnd,
|
||||
malEnvPtr env) const = 0;
|
||||
malValueIter argsEnd) const = 0;
|
||||
};
|
||||
|
||||
class malHash : public malValue {
|
||||
@ -263,8 +262,7 @@ class malBuiltIn : public malApplicable {
|
||||
public:
|
||||
typedef malValuePtr (ApplyFunc)(const String& name,
|
||||
malValueIter argsBegin,
|
||||
malValueIter argsEnd,
|
||||
malEnvPtr env);
|
||||
malValueIter argsEnd);
|
||||
|
||||
malBuiltIn(const String& name, ApplyFunc* handler)
|
||||
: m_name(name), m_handler(handler) { }
|
||||
@ -273,8 +271,7 @@ public:
|
||||
: malApplicable(meta), m_name(that.m_name), m_handler(that.m_handler) { }
|
||||
|
||||
virtual malValuePtr apply(malValueIter argsBegin,
|
||||
malValueIter argsEnd,
|
||||
malEnvPtr env) const;
|
||||
malValueIter argsEnd) const;
|
||||
|
||||
virtual String print(bool readably) const {
|
||||
return STRF("#builtin-function(%s)", m_name.c_str());
|
||||
@ -300,8 +297,7 @@ public:
|
||||
malLambda(const malLambda& that, bool isMacro);
|
||||
|
||||
virtual malValuePtr apply(malValueIter argsBegin,
|
||||
malValueIter argsEnd,
|
||||
malEnvPtr env) const;
|
||||
malValueIter argsEnd) const;
|
||||
|
||||
malValuePtr getBody() const { return m_body; }
|
||||
malEnvPtr makeEnv(malValueIter argsBegin, malValueIter argsEnd) const;
|
||||
|
@ -60,7 +60,7 @@ malValuePtr EVAL(malValuePtr ast, malEnvPtr)
|
||||
return ast;
|
||||
}
|
||||
|
||||
malValuePtr APPLY(malValuePtr ast, malValueIter, malValueIter, malEnvPtr)
|
||||
malValuePtr APPLY(malValuePtr ast, malValueIter, malValueIter)
|
||||
{
|
||||
return ast;
|
||||
}
|
||||
|
@ -59,14 +59,13 @@ String PRINT(malValuePtr ast)
|
||||
return ast->print(true);
|
||||
}
|
||||
|
||||
malValuePtr APPLY(malValuePtr op, malValueIter argsBegin, malValueIter argsEnd,
|
||||
malEnvPtr env)
|
||||
malValuePtr APPLY(malValuePtr op, malValueIter argsBegin, malValueIter argsEnd)
|
||||
{
|
||||
const malApplicable* handler = DYNAMIC_CAST(malApplicable, op);
|
||||
MAL_CHECK(handler != NULL,
|
||||
"\"%s\" is not applicable", op->print(true).c_str());
|
||||
|
||||
return handler->apply(argsBegin, argsEnd, env);
|
||||
return handler->apply(argsBegin, argsEnd);
|
||||
}
|
||||
|
||||
#define ARG(type, name) type* name = VALUE_CAST(type, *argsBegin++)
|
||||
@ -79,7 +78,7 @@ malValuePtr APPLY(malValuePtr op, malValueIter argsBegin, malValueIter argsEnd,
|
||||
|
||||
|
||||
static malValuePtr builtIn_add(const String& name,
|
||||
malValueIter argsBegin, malValueIter argsEnd, malEnvPtr env)
|
||||
malValueIter argsBegin, malValueIter argsEnd)
|
||||
{
|
||||
CHECK_ARGS_IS(2);
|
||||
ARG(malInteger, lhs);
|
||||
@ -88,7 +87,7 @@ static malValuePtr builtIn_add(const String& name,
|
||||
}
|
||||
|
||||
static malValuePtr builtIn_sub(const String& name,
|
||||
malValueIter argsBegin, malValueIter argsEnd, malEnvPtr env)
|
||||
malValueIter argsBegin, malValueIter argsEnd)
|
||||
{
|
||||
int argCount = CHECK_ARGS_BETWEEN(1, 2);
|
||||
ARG(malInteger, lhs);
|
||||
@ -100,7 +99,7 @@ static malValuePtr builtIn_sub(const String& name,
|
||||
}
|
||||
|
||||
static malValuePtr builtIn_mul(const String& name,
|
||||
malValueIter argsBegin, malValueIter argsEnd, malEnvPtr env)
|
||||
malValueIter argsBegin, malValueIter argsEnd)
|
||||
{
|
||||
CHECK_ARGS_IS(2);
|
||||
ARG(malInteger, lhs);
|
||||
@ -109,7 +108,7 @@ static malValuePtr builtIn_mul(const String& name,
|
||||
}
|
||||
|
||||
static malValuePtr builtIn_div(const String& name,
|
||||
malValueIter argsBegin, malValueIter argsEnd, malEnvPtr env)
|
||||
malValueIter argsBegin, malValueIter argsEnd)
|
||||
{
|
||||
CHECK_ARGS_IS(2);
|
||||
ARG(malInteger, lhs);
|
||||
|
@ -12,11 +12,12 @@ String PRINT(malValuePtr ast);
|
||||
|
||||
static ReadLine s_readLine("~/.mal-history");
|
||||
|
||||
static malEnvPtr replEnv(new malEnv);
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
String prompt = "user> ";
|
||||
String input;
|
||||
malEnvPtr replEnv(new malEnv);
|
||||
installCore(replEnv);
|
||||
while (s_readLine.get(prompt, input)) {
|
||||
String out;
|
||||
@ -46,6 +47,9 @@ malValuePtr READ(const String& input)
|
||||
|
||||
malValuePtr EVAL(malValuePtr ast, malEnvPtr env)
|
||||
{
|
||||
if (!env) {
|
||||
env = replEnv;
|
||||
}
|
||||
const malList* list = DYNAMIC_CAST(malList, ast);
|
||||
if (!list || (list->count() == 0)) {
|
||||
return ast->eval(env);
|
||||
@ -81,7 +85,7 @@ malValuePtr EVAL(malValuePtr ast, malEnvPtr env)
|
||||
// Now we're left with the case of a regular list to be evaluated.
|
||||
std::unique_ptr<malValueVec> items(list->evalItems(env));
|
||||
malValuePtr op = items->at(0);
|
||||
return APPLY(op, items->begin()+1, items->end(), env);
|
||||
return APPLY(op, items->begin()+1, items->end());
|
||||
}
|
||||
|
||||
String PRINT(malValuePtr ast)
|
||||
@ -89,14 +93,13 @@ String PRINT(malValuePtr ast)
|
||||
return ast->print(true);
|
||||
}
|
||||
|
||||
malValuePtr APPLY(malValuePtr op, malValueIter argsBegin, malValueIter argsEnd,
|
||||
malEnvPtr env)
|
||||
malValuePtr APPLY(malValuePtr op, malValueIter argsBegin, malValueIter argsEnd)
|
||||
{
|
||||
const malApplicable* handler = DYNAMIC_CAST(malApplicable, op);
|
||||
MAL_CHECK(handler != NULL,
|
||||
"\"%s\" is not applicable", op->print(true).c_str());
|
||||
|
||||
return handler->apply(argsBegin, argsEnd, env);
|
||||
return handler->apply(argsBegin, argsEnd);
|
||||
}
|
||||
|
||||
// Added to keep the linker happy at step A
|
||||
|
@ -13,11 +13,12 @@ static void installFunctions(malEnvPtr env);
|
||||
|
||||
static ReadLine s_readLine("~/.mal-history");
|
||||
|
||||
static malEnvPtr replEnv(new malEnv);
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
String prompt = "user> ";
|
||||
String input;
|
||||
malEnvPtr replEnv(new malEnv);
|
||||
installCore(replEnv);
|
||||
installFunctions(replEnv);
|
||||
while (s_readLine.get(prompt, input)) {
|
||||
@ -48,6 +49,9 @@ malValuePtr READ(const String& input)
|
||||
|
||||
malValuePtr EVAL(malValuePtr ast, malEnvPtr env)
|
||||
{
|
||||
if (!env) {
|
||||
env = replEnv;
|
||||
}
|
||||
const malList* list = DYNAMIC_CAST(malList, ast);
|
||||
if (!list || (list->count() == 0)) {
|
||||
return ast->eval(env);
|
||||
@ -122,7 +126,7 @@ malValuePtr EVAL(malValuePtr ast, malEnvPtr env)
|
||||
lambda->makeEnv(items->begin()+1, items->end()));
|
||||
}
|
||||
else {
|
||||
return APPLY(op, items->begin()+1, items->end(), env);
|
||||
return APPLY(op, items->begin()+1, items->end());
|
||||
}
|
||||
}
|
||||
|
||||
@ -131,14 +135,13 @@ String PRINT(malValuePtr ast)
|
||||
return ast->print(true);
|
||||
}
|
||||
|
||||
malValuePtr APPLY(malValuePtr op, malValueIter argsBegin, malValueIter argsEnd,
|
||||
malEnvPtr env)
|
||||
malValuePtr APPLY(malValuePtr op, malValueIter argsBegin, malValueIter argsEnd)
|
||||
{
|
||||
const malApplicable* handler = DYNAMIC_CAST(malApplicable, op);
|
||||
MAL_CHECK(handler != NULL,
|
||||
"\"%s\" is not applicable", op->print(true).c_str());
|
||||
|
||||
return handler->apply(argsBegin, argsEnd, env);
|
||||
return handler->apply(argsBegin, argsEnd);
|
||||
}
|
||||
|
||||
static const char* malFunctionTable[] = {
|
||||
|
@ -13,11 +13,12 @@ static void installFunctions(malEnvPtr env);
|
||||
|
||||
static ReadLine s_readLine("~/.mal-history");
|
||||
|
||||
static malEnvPtr replEnv(new malEnv);
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
String prompt = "user> ";
|
||||
String input;
|
||||
malEnvPtr replEnv(new malEnv);
|
||||
installCore(replEnv);
|
||||
installFunctions(replEnv);
|
||||
while (s_readLine.get(prompt, input)) {
|
||||
@ -48,6 +49,9 @@ malValuePtr READ(const String& input)
|
||||
|
||||
malValuePtr EVAL(malValuePtr ast, malEnvPtr env)
|
||||
{
|
||||
if (!env) {
|
||||
env = replEnv;
|
||||
}
|
||||
while (1) {
|
||||
const malList* list = DYNAMIC_CAST(malList, ast);
|
||||
if (!list || (list->count() == 0)) {
|
||||
@ -128,7 +132,7 @@ malValuePtr EVAL(malValuePtr ast, malEnvPtr env)
|
||||
continue; // TCO
|
||||
}
|
||||
else {
|
||||
return APPLY(op, items->begin()+1, items->end(), env);
|
||||
return APPLY(op, items->begin()+1, items->end());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -138,14 +142,13 @@ String PRINT(malValuePtr ast)
|
||||
return ast->print(true);
|
||||
}
|
||||
|
||||
malValuePtr APPLY(malValuePtr op, malValueIter argsBegin, malValueIter argsEnd,
|
||||
malEnvPtr env)
|
||||
malValuePtr APPLY(malValuePtr op, malValueIter argsBegin, malValueIter argsEnd)
|
||||
{
|
||||
const malApplicable* handler = DYNAMIC_CAST(malApplicable, op);
|
||||
MAL_CHECK(handler != NULL,
|
||||
"\"%s\" is not applicable", op->print(true).c_str());
|
||||
|
||||
return handler->apply(argsBegin, argsEnd, env);
|
||||
return handler->apply(argsBegin, argsEnd);
|
||||
}
|
||||
|
||||
static const char* malFunctionTable[] = {
|
||||
|
@ -16,11 +16,12 @@ static void safeRep(const String& input, malEnvPtr env);
|
||||
|
||||
static ReadLine s_readLine("~/.mal-history");
|
||||
|
||||
static malEnvPtr replEnv(new malEnv);
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
String prompt = "user> ";
|
||||
String input;
|
||||
malEnvPtr replEnv(new malEnv);
|
||||
installCore(replEnv);
|
||||
installFunctions(replEnv);
|
||||
makeArgv(replEnv, argc - 2, argv + 2);
|
||||
@ -71,6 +72,9 @@ malValuePtr READ(const String& input)
|
||||
|
||||
malValuePtr EVAL(malValuePtr ast, malEnvPtr env)
|
||||
{
|
||||
if (!env) {
|
||||
env = replEnv;
|
||||
}
|
||||
while (1) {
|
||||
const malList* list = DYNAMIC_CAST(malList, ast);
|
||||
if (!list || (list->count() == 0)) {
|
||||
@ -151,7 +155,7 @@ malValuePtr EVAL(malValuePtr ast, malEnvPtr env)
|
||||
continue; // TCO
|
||||
}
|
||||
else {
|
||||
return APPLY(op, items->begin()+1, items->end(), env);
|
||||
return APPLY(op, items->begin()+1, items->end());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -161,14 +165,13 @@ String PRINT(malValuePtr ast)
|
||||
return ast->print(true);
|
||||
}
|
||||
|
||||
malValuePtr APPLY(malValuePtr op, malValueIter argsBegin, malValueIter argsEnd,
|
||||
malEnvPtr env)
|
||||
malValuePtr APPLY(malValuePtr op, malValueIter argsBegin, malValueIter argsEnd)
|
||||
{
|
||||
const malApplicable* handler = DYNAMIC_CAST(malApplicable, op);
|
||||
MAL_CHECK(handler != NULL,
|
||||
"\"%s\" is not applicable", op->print(true).c_str());
|
||||
|
||||
return handler->apply(argsBegin, argsEnd, env);
|
||||
return handler->apply(argsBegin, argsEnd);
|
||||
}
|
||||
|
||||
static const char* malFunctionTable[] = {
|
||||
|
@ -17,11 +17,12 @@ static malValuePtr quasiquote(malValuePtr obj);
|
||||
|
||||
static ReadLine s_readLine("~/.mal-history");
|
||||
|
||||
static malEnvPtr replEnv(new malEnv);
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
String prompt = "user> ";
|
||||
String input;
|
||||
malEnvPtr replEnv(new malEnv);
|
||||
installCore(replEnv);
|
||||
installFunctions(replEnv);
|
||||
makeArgv(replEnv, argc - 2, argv + 2);
|
||||
@ -72,6 +73,9 @@ malValuePtr READ(const String& input)
|
||||
|
||||
malValuePtr EVAL(malValuePtr ast, malEnvPtr env)
|
||||
{
|
||||
if (!env) {
|
||||
env = replEnv;
|
||||
}
|
||||
while (1) {
|
||||
const malList* list = DYNAMIC_CAST(malList, ast);
|
||||
if (!list || (list->count() == 0)) {
|
||||
@ -163,7 +167,7 @@ malValuePtr EVAL(malValuePtr ast, malEnvPtr env)
|
||||
continue; // TCO
|
||||
}
|
||||
else {
|
||||
return APPLY(op, items->begin()+1, items->end(), env);
|
||||
return APPLY(op, items->begin()+1, items->end());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -173,14 +177,13 @@ String PRINT(malValuePtr ast)
|
||||
return ast->print(true);
|
||||
}
|
||||
|
||||
malValuePtr APPLY(malValuePtr op, malValueIter argsBegin, malValueIter argsEnd,
|
||||
malEnvPtr env)
|
||||
malValuePtr APPLY(malValuePtr op, malValueIter argsBegin, malValueIter argsEnd)
|
||||
{
|
||||
const malApplicable* handler = DYNAMIC_CAST(malApplicable, op);
|
||||
MAL_CHECK(handler != NULL,
|
||||
"\"%s\" is not applicable", op->print(true).c_str());
|
||||
|
||||
return handler->apply(argsBegin, argsEnd, env);
|
||||
return handler->apply(argsBegin, argsEnd);
|
||||
}
|
||||
|
||||
static bool isSymbol(malValuePtr obj, const String& text)
|
||||
|
@ -19,11 +19,12 @@ static void installMacros(malEnvPtr env);
|
||||
|
||||
static ReadLine s_readLine("~/.mal-history");
|
||||
|
||||
static malEnvPtr replEnv(new malEnv);
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
String prompt = "user> ";
|
||||
String input;
|
||||
malEnvPtr replEnv(new malEnv);
|
||||
installCore(replEnv);
|
||||
installFunctions(replEnv);
|
||||
installMacros(replEnv);
|
||||
@ -75,6 +76,9 @@ malValuePtr READ(const String& input)
|
||||
|
||||
malValuePtr EVAL(malValuePtr ast, malEnvPtr env)
|
||||
{
|
||||
if (!env) {
|
||||
env = replEnv;
|
||||
}
|
||||
while (1) {
|
||||
const malList* list = DYNAMIC_CAST(malList, ast);
|
||||
if (!list || (list->count() == 0)) {
|
||||
@ -186,7 +190,7 @@ malValuePtr EVAL(malValuePtr ast, malEnvPtr env)
|
||||
continue; // TCO
|
||||
}
|
||||
else {
|
||||
return APPLY(op, items->begin()+1, items->end(), env);
|
||||
return APPLY(op, items->begin()+1, items->end());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -196,14 +200,13 @@ String PRINT(malValuePtr ast)
|
||||
return ast->print(true);
|
||||
}
|
||||
|
||||
malValuePtr APPLY(malValuePtr op, malValueIter argsBegin, malValueIter argsEnd,
|
||||
malEnvPtr env)
|
||||
malValuePtr APPLY(malValuePtr op, malValueIter argsBegin, malValueIter argsEnd)
|
||||
{
|
||||
const malApplicable* handler = DYNAMIC_CAST(malApplicable, op);
|
||||
MAL_CHECK(handler != NULL,
|
||||
"\"%s\" is not applicable", op->print(true).c_str());
|
||||
|
||||
return handler->apply(argsBegin, argsEnd, env);
|
||||
return handler->apply(argsBegin, argsEnd);
|
||||
}
|
||||
|
||||
static bool isSymbol(malValuePtr obj, const String& text)
|
||||
@ -271,7 +274,7 @@ static malValuePtr macroExpand(malValuePtr obj, malEnvPtr env)
|
||||
{
|
||||
while (const malLambda* macro = isMacroApplication(obj, env)) {
|
||||
const malSequence* seq = STATIC_CAST(malSequence, obj);
|
||||
obj = macro->apply(seq->begin() + 1, seq->end(), env);
|
||||
obj = macro->apply(seq->begin() + 1, seq->end());
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
|
@ -19,11 +19,12 @@ static void installMacros(malEnvPtr env);
|
||||
|
||||
static ReadLine s_readLine("~/.mal-history");
|
||||
|
||||
static malEnvPtr replEnv(new malEnv);
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
String prompt = "user> ";
|
||||
String input;
|
||||
malEnvPtr replEnv(new malEnv);
|
||||
installCore(replEnv);
|
||||
installFunctions(replEnv);
|
||||
installMacros(replEnv);
|
||||
@ -75,6 +76,9 @@ malValuePtr READ(const String& input)
|
||||
|
||||
malValuePtr EVAL(malValuePtr ast, malEnvPtr env)
|
||||
{
|
||||
if (!env) {
|
||||
env = replEnv;
|
||||
}
|
||||
while (1) {
|
||||
const malList* list = DYNAMIC_CAST(malList, ast);
|
||||
if (!list || (list->count() == 0)) {
|
||||
@ -227,7 +231,7 @@ malValuePtr EVAL(malValuePtr ast, malEnvPtr env)
|
||||
continue; // TCO
|
||||
}
|
||||
else {
|
||||
return APPLY(op, items->begin()+1, items->end(), env);
|
||||
return APPLY(op, items->begin()+1, items->end());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -237,14 +241,13 @@ String PRINT(malValuePtr ast)
|
||||
return ast->print(true);
|
||||
}
|
||||
|
||||
malValuePtr APPLY(malValuePtr op, malValueIter argsBegin, malValueIter argsEnd,
|
||||
malEnvPtr env)
|
||||
malValuePtr APPLY(malValuePtr op, malValueIter argsBegin, malValueIter argsEnd)
|
||||
{
|
||||
const malApplicable* handler = DYNAMIC_CAST(malApplicable, op);
|
||||
MAL_CHECK(handler != NULL,
|
||||
"\"%s\" is not applicable", op->print(true).c_str());
|
||||
|
||||
return handler->apply(argsBegin, argsEnd, env);
|
||||
return handler->apply(argsBegin, argsEnd);
|
||||
}
|
||||
|
||||
static bool isSymbol(malValuePtr obj, const String& text)
|
||||
@ -312,7 +315,7 @@ static malValuePtr macroExpand(malValuePtr obj, malEnvPtr env)
|
||||
{
|
||||
while (const malLambda* macro = isMacroApplication(obj, env)) {
|
||||
const malSequence* seq = STATIC_CAST(malSequence, obj);
|
||||
obj = macro->apply(seq->begin() + 1, seq->end(), env);
|
||||
obj = macro->apply(seq->begin() + 1, seq->end());
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
|
@ -19,11 +19,12 @@ static void installMacros(malEnvPtr env);
|
||||
|
||||
static ReadLine s_readLine("~/.mal-history");
|
||||
|
||||
static malEnvPtr replEnv(new malEnv);
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
String prompt = "user> ";
|
||||
String input;
|
||||
malEnvPtr replEnv(new malEnv);
|
||||
installCore(replEnv);
|
||||
installFunctions(replEnv);
|
||||
installMacros(replEnv);
|
||||
@ -75,6 +76,9 @@ malValuePtr READ(const String& input)
|
||||
|
||||
malValuePtr EVAL(malValuePtr ast, malEnvPtr env)
|
||||
{
|
||||
if (!env) {
|
||||
env = replEnv;
|
||||
}
|
||||
while (1) {
|
||||
const malList* list = DYNAMIC_CAST(malList, ast);
|
||||
if (!list || (list->count() == 0)) {
|
||||
@ -227,7 +231,7 @@ malValuePtr EVAL(malValuePtr ast, malEnvPtr env)
|
||||
continue; // TCO
|
||||
}
|
||||
else {
|
||||
return APPLY(op, items->begin()+1, items->end(), env);
|
||||
return APPLY(op, items->begin()+1, items->end());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -237,14 +241,13 @@ String PRINT(malValuePtr ast)
|
||||
return ast->print(true);
|
||||
}
|
||||
|
||||
malValuePtr APPLY(malValuePtr op, malValueIter argsBegin, malValueIter argsEnd,
|
||||
malEnvPtr env)
|
||||
malValuePtr APPLY(malValuePtr op, malValueIter argsBegin, malValueIter argsEnd)
|
||||
{
|
||||
const malApplicable* handler = DYNAMIC_CAST(malApplicable, op);
|
||||
MAL_CHECK(handler != NULL,
|
||||
"\"%s\" is not applicable", op->print(true).c_str());
|
||||
|
||||
return handler->apply(argsBegin, argsEnd, env);
|
||||
return handler->apply(argsBegin, argsEnd);
|
||||
}
|
||||
|
||||
static bool isSymbol(malValuePtr obj, const String& text)
|
||||
@ -312,7 +315,7 @@ static malValuePtr macroExpand(malValuePtr obj, malEnvPtr env)
|
||||
{
|
||||
while (const malLambda* macro = isMacroApplication(obj, env)) {
|
||||
const malSequence* seq = STATIC_CAST(malSequence, obj);
|
||||
obj = macro->apply(seq->begin() + 1, seq->end(), env);
|
||||
obj = macro->apply(seq->begin() + 1, seq->end());
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
@ -348,7 +351,6 @@ static const char* malFunctionTable[] = {
|
||||
(eval (read-string (str \"(do \" (slurp filename) \")\")))))",
|
||||
"(def! map (fn* (f xs) (if (empty? xs) xs \
|
||||
(cons (f (first xs)) (map f (rest xs))))))",
|
||||
"(def! swap! (fn* (atom f & args) (reset! atom (apply f @atom args))))",
|
||||
"(def! *host-language* \"c++\")",
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user