aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2009-01-23 18:59:58 +0000
committerDavid Robillard <d@drobilla.net>2009-01-23 18:59:58 +0000
commita49206460b255e6006be698addb7f6fac5d57c43 (patch)
tree98647bfed4455d7d3222468526951d1025dfcce8
parent3ca89c7718f611e06e5a6108c0ead28b414f5083 (diff)
downloadresp-a49206460b255e6006be698addb7f6fac5d57c43.tar.gz
resp-a49206460b255e6006be698addb7f6fac5d57c43.tar.bz2
resp-a49206460b255e6006be698addb7f6fac5d57c43.zip
Fix sticky REPL value problem.
git-svn-id: http://svn.drobilla.net/resp/llvm-lisp@8 ad02d1e2-f140-0410-9f75-f8b11f17cedd
-rw-r--r--ll.cpp41
1 files changed, 22 insertions, 19 deletions
diff --git a/ll.cpp b/ll.cpp
index cc13b31..1633468 100644
--- a/ll.cpp
+++ b/ll.cpp
@@ -24,6 +24,7 @@
#include <stack>
#include <string>
#include <vector>
+#include <sstream>
#include "llvm/Analysis/Verifier.h"
#include "llvm/DerivedTypes.h"
#include "llvm/ExecutionEngine/ExecutionEngine.h"
@@ -174,13 +175,12 @@ struct ASTPrimitive : public ASTCall {
/// Function prototype
struct ASTPrototype : public AST {
- ASTPrototype(bool foreign, const string& n, const vector<string>& p)
- : _foreign(foreign), _name(n), _params(p) {}
+ ASTPrototype(const string& n, const vector<string>& p=vector<string>())
+ : _name(n), _params(p) {}
virtual bool evaluatable() const { return false; }
Value* Codegen(CEnv& cenv) { return Funcgen(cenv); }
Function* Funcgen(CEnv& cenv);
private:
- bool _foreign;
string _name;
vector<string> _params;
};
@@ -222,7 +222,7 @@ parseSymbol(const SExp& exp)
/// prototype ::= (name [arg*])
static ASTPrototype*
-parsePrototype(bool foreign, const SExp& exp)
+parsePrototype(const SExp& exp)
{
list<SExp>::const_iterator i = exp.list.begin();
const string& name = i->atom;
@@ -234,7 +234,7 @@ parsePrototype(bool foreign, const SExp& exp)
else
throw SyntaxError("Expected parameter name, found list");
- return new ASTPrototype(foreign, name, args);
+ return new ASTPrototype(name, args);
}
/// callexpr ::= (expression [...])
@@ -248,7 +248,7 @@ parseCall(const SExp& exp)
const string& name = i->atom;
if (name == "def" && (++i)->type == SExp::LIST) {
- ASTPrototype* proto = parsePrototype(false, *i++);
+ ASTPrototype* proto = parsePrototype(*i++);
AST* body = parseExpression(*i++);
return new ASTFunction(proto, body);
}
@@ -268,7 +268,7 @@ parseCall(const SExp& exp)
} else if (name == "def") {
return new ASTDefinition(name, args);
} else if (name == "foreign") {
- return parsePrototype(true, *++i++);
+ return parsePrototype(*++i++);
}
return new ASTCall(name, args);
@@ -296,7 +296,7 @@ parseExpression(const SExp& exp)
/// Compile-time environment
struct CEnv {
CEnv(Module* m, const TargetData* target)
- : module(m), provider(module), fpm(&provider)
+ : module(m), provider(module), fpm(&provider), id(0)
{
// Set up the optimizer pipeline.
// Register info about how the target lays out data structures.
@@ -310,11 +310,15 @@ struct CEnv {
// Simplify control flow graph (delete unreachable blocks, etc).
fpm.add(createCFGSimplificationPass());
}
+ string gensym(const char* base="_") {
+ ostringstream s; s << base << id++; return s.str();
+ }
IRBuilder<> builder;
Module* module;
ExistingModuleProvider provider;
FunctionPassManager fpm;
map<string, Value*> env;
+ size_t id;
};
Value*
@@ -428,11 +432,10 @@ ASTPrototype::Funcgen(CEnv& cenv)
throw SyntaxError("Function redefined with mismatched arguments");
}
- // Set names for all arguments and add to environment.
Function::arg_iterator a = f->arg_begin();
for (size_t i = 0; i != _params.size(); ++a, ++i) {
- a->setName(_params[i]);
- cenv.env[_params[i]] = a;
+ a->setName(_params[i]); // Set name in generated code
+ cenv.env[_params[i]] = a; // Add to environment
}
return f;
@@ -467,14 +470,14 @@ ASTPrimitive::Codegen(CEnv& cenv)
Instruction::BinaryOps op;
assert(_name.length() == 1);
switch (_name[0]) {
- case '+': op = Instruction::Add; break;
- case '-': op = Instruction::Sub; break;
- case '*': op = Instruction::Mul; break;
+ case '+': op = Instruction::Add; break;
+ case '-': op = Instruction::Sub; break;
+ case '*': op = Instruction::Mul; break;
case '/': op = Instruction::FDiv; break;
case '%': op = Instruction::FRem; break;
- case '&': op = Instruction::And; break;
- case '|': op = Instruction::Or; break;
- case '^': op = Instruction::Xor; break;
+ case '&': op = Instruction::And; break;
+ case '|': op = Instruction::Or; break;
+ case '^': op = Instruction::Xor; break;
default: throw SyntaxError("Unknown primitive");
}
@@ -516,13 +519,13 @@ repl(CEnv& cenv, ExecutionEngine* engine)
if (!ast)
continue;
if (ast->evaluatable()) {
- ASTPrototype* proto = new ASTPrototype(false, "", vector<string>());
+ ASTPrototype* proto = new ASTPrototype(cenv.gensym("repl"));
ASTFunction* func = new ASTFunction(proto, ast);
Function* code = func->Funcgen(cenv);
void* fp = engine->getPointerToFunction(code);
double (*f)() = (double (*)())fp;
std::cout << f() << endl;
- code->eraseFromParent();
+ //code->eraseFromParent();
} else {
Value* code = ast->Codegen(cenv);
std::cout << "Generated code:" << endl;