diff options
author | David Robillard <d@drobilla.net> | 2009-01-23 18:59:58 +0000 |
---|---|---|
committer | David Robillard <d@drobilla.net> | 2009-01-23 18:59:58 +0000 |
commit | a49206460b255e6006be698addb7f6fac5d57c43 (patch) | |
tree | 98647bfed4455d7d3222468526951d1025dfcce8 | |
parent | 3ca89c7718f611e06e5a6108c0ead28b414f5083 (diff) | |
download | resp-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.cpp | 41 |
1 files changed, 22 insertions, 19 deletions
@@ -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; |