aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--ll.cpp129
1 files changed, 40 insertions, 89 deletions
diff --git a/ll.cpp b/ll.cpp
index a38242b..bf2b48a 100644
--- a/ll.cpp
+++ b/ll.cpp
@@ -245,14 +245,9 @@ static AST* parseIfExpr(const SExp& exp)
list<SExp>::const_iterator i = exp.list.begin();
++i;
- AST* cond = parseExpression(*i++);
- if (!cond) return 0;
-
- AST* then = parseExpression(*i++);
- if (!then) return 0;
-
+ AST* cond = parseExpression(*i++);
+ AST* then = parseExpression(*i++);
AST* otherwise = parseExpression(*i++);
- if (!otherwise) return 0;
return new ASTIf(cond, then, otherwise);
}
@@ -266,10 +261,7 @@ static AST* parseCallExpr(const SExp& exp)
vector<AST*> params;
for (++i; i != exp.list.end(); ++i)
- if (AST* p = parseExpression(*i))
- params.push_back(p);
- else
- return 0;
+ params.push_back(parseExpression(*i));
return new ASTCall(name, params);
}
@@ -299,12 +291,9 @@ static ASTFunction* parseDefinition(const SExp& exp)
++i;
ASTPrototype* proto = ParsePrototype(false, *i++);
- if (proto == 0) return 0;
-
- if (AST* body = parseExpression(*i++))
- return new ASTFunction(proto, body);
-
- return 0;
+ AST* body = parseExpression(*i++);
+
+ return new ASTFunction(proto, body);
}
/// foreign ::= ("foreign" prototype expression)
@@ -321,9 +310,7 @@ static AST* parseExpression(const SExp& exp)
{
if (exp.type == SExp::LIST) {
const string& form = head(exp);
- if (exp.list.empty()) {
- return NULL;
- } else if (form == "if") {
+ if (form == "if") {
return parseIfExpr(exp);
} else if (form == "def") {
return parseDefinition(exp);
@@ -337,7 +324,7 @@ static AST* parseExpression(const SExp& exp)
} else if (isdigit(exp.atom[0])) {
return parseNumberExpr(exp);
} else {
- return NULL;
+ throw SyntaxError("Illegal atom");
}
}
@@ -383,29 +370,21 @@ Value* ASTNumber::Codegen(CEnv& cenv)
Value* ASTVariable::Codegen(CEnv& cenv)
{
- // Look this variable up in the function.
map<string, Value*>::const_iterator v = cenv.env.find(_name);
- if (v != cenv.env.end())
- return v->second;
- else
- return ErrorV("Unknown variable name");
+ if (v == cenv.env.end()) throw SyntaxError("Undefined identifier");
+ return v->second;
}
Value* ASTCall::Codegen(CEnv& cenv)
{
// Look up the name in the global module table.
Function* f = cenv.module->getFunction(_func);
- if (f == 0)
- return ErrorV("Unknown function referenced");
-
- if (f->arg_size() != _args.size())
- return ErrorV("Incorrect # arguments passed");
+ if (f == 0) throw SyntaxError("Undefined function");
+ if (f->arg_size() != _args.size()) throw SyntaxError("Illegal arguments");
vector<Value*> args;
- for (size_t i = 0, e = _args.size(); i != e; ++i) {
+ for (size_t i = 0, e = _args.size(); i != e; ++i)
args.push_back(_args[i]->Codegen(cenv));
- if (args.back() == 0) return 0;
- }
return cenv.builder.CreateCall(f, args.begin(), args.end(), "calltmp");
}
@@ -413,7 +392,6 @@ Value* ASTCall::Codegen(CEnv& cenv)
Value* ASTIf::Codegen(CEnv& cenv)
{
Value* condV = _cond->Codegen(cenv);
- if (condV == 0) return 0;
// Convert condition to a bool by comparing equal to 0.0.
condV = cenv.builder.CreateFCmpONE(
@@ -433,7 +411,6 @@ Value* ASTIf::Codegen(CEnv& cenv)
cenv.builder.SetInsertPoint(thenBB);
Value* thenV = _then->Codegen(cenv);
- if (thenV == 0) return 0;
cenv.builder.CreateBr(mergeBB);
// Codegen of 'Then' can change the current block, update thenBB
@@ -444,7 +421,6 @@ Value* ASTIf::Codegen(CEnv& cenv)
cenv.builder.SetInsertPoint(elseBB);
Value* elseV = _else->Codegen(cenv);
- if (elseV == 0) return 0;
cenv.builder.CreateBr(mergeBB);
// Codegen of 'Else' can change the current block, update elseBB
@@ -466,39 +442,35 @@ Function* ASTPrototype::Funcgen(CEnv& cenv)
vector<const Type*> Doubles(_args.size(), Type::DoubleTy);
FunctionType* FT = FunctionType::get(Type::DoubleTy, Doubles, false);
- Function* F = Function::Create(FT, Function::ExternalLinkage, _name, cenv.module);
+ Function* f = Function::Create(
+ FT, Function::ExternalLinkage, _name, cenv.module);
// If F conflicted, there was already something named 'Name'.
// If it has a body, don't allow redefinition.
- if (F->getName() != _name) {
+ if (f->getName() != _name) {
// Delete the one we just made and get the existing one.
- F->eraseFromParent();
- F = cenv.module->getFunction(_name);
+ f->eraseFromParent();
+ f = cenv.module->getFunction(_name);
// If F already has a body, reject this.
- if (!F->empty()) {
- ErrorF(string("Redefinition of function '").append(_name).append("'").c_str());
- return 0;
- }
+ if (!f->empty()) throw SyntaxError("Function redefined");
// If F took a different number of args, reject.
- if (F->arg_size() != _args.size()) {
- ErrorF("Redefinition of function with different # args");
- return 0;
- }
+ if (f->arg_size() != _args.size())
+ throw SyntaxError("Function redefined with mismatched arguments");
}
// Set names for all arguments.
- unsigned Idx = 0;
- for (Function::arg_iterator AI = F->arg_begin(); Idx != _args.size();
- ++AI, ++Idx) {
- AI->setName(_args[Idx]);
+ size_t i = 0;
+ for (Function::arg_iterator a = f->arg_begin(); i != _args.size();
+ ++a, ++i) {
+ a->setName(_args[i]);
// Add arguments to variable symbol table.
- cenv.env[_args[Idx]] = AI;
+ cenv.env[_args[i]] = a;
}
- return F;
+ return f;
}
Function* ASTFunction::Funcgen(CEnv& cenv)
@@ -506,29 +478,23 @@ Function* ASTFunction::Funcgen(CEnv& cenv)
cenv.env.clear();
Function* f = _proto->Funcgen(cenv);
- if (f == 0)
- return 0;
// Create a new basic block to start insertion into.
BasicBlock* bb = BasicBlock::Create("entry", f);
cenv.builder.SetInsertPoint(bb);
- if (Value* retVal = _body->Codegen(cenv)) {
- // Finish off the function.
- cenv.builder.CreateRet(retVal);
-
- // Validate the generated code, checking for consistency.
- verifyFunction(*f);
-
- // Optimize the function.
- cenv.fpm.run(*f);
-
+ try {
+ Value* retVal = _body->Codegen(cenv);
+ cenv.builder.CreateRet(retVal); // Finish function
+ verifyFunction(*f); // Validate generated code
+ cenv.fpm.run(*f); // Optimize function
return f;
+ } catch (std::exception e) {
+ f->eraseFromParent(); // Error reading body, remove function
+ throw e;
}
- // Error reading body, remove function.
- f->eraseFromParent();
- return 0;
+ return 0; // Never reached
}
@@ -544,7 +510,8 @@ static void repl(CEnv& cenv, ExecutionEngine* engine)
std::cout.flush();
SExp exp = readExpression(std::cin);
- if (AST* ast = parseExpression(exp)) {
+ try {
+ AST* ast = parseExpression(exp);
if (ast->evaluatable()) {
ASTPrototype* proto = new ASTPrototype(false, "", vector<string>());
ASTFunction* func = new ASTFunction(proto, ast);
@@ -557,30 +524,14 @@ static void repl(CEnv& cenv, ExecutionEngine* engine)
std::cout << "Generated code:" << endl;
code->dump();
}
- } else {
- break;
+ } catch (SyntaxError e) {
+ std::cerr << "Syntax error: " << e.what() << endl;
}
}
}
/***************************************************************************
- * "Library" functions that can be "extern'd" from user code. *
- ***************************************************************************/
-
-extern "C" {
-
-double
-putchard(double X)
-{
- putchar((char)X);
- return 0;
-}
-
-} // extern "C"
-
-
-/***************************************************************************
* Main driver code.
***************************************************************************/