From ed78a6054c628e80240eff8ea9a06412774df094 Mon Sep 17 00:00:00 2001 From: Clyne Sullivan Date: Sat, 15 Jun 2024 11:54:19 -0400 Subject: [PATCH] some error reporting --- Makefile | 2 +- ast.cpp | 18 ++++++++++++++++-- llvm.cpp | 3 +-- main.cpp | 29 +++++++++++++++++------------ 4 files changed, 35 insertions(+), 17 deletions(-) diff --git a/Makefile b/Makefile index c7761c0..caa1558 100644 --- a/Makefile +++ b/Makefile @@ -8,7 +8,7 @@ main: $(subst .cpp,.o,$(CXXFILES)) $(CXX) -o $@ $^ $(CXXFLAGS) $(LDFLAGS) prog: main test.fp - ./main < test.fp 2> forsp.ir + ./main < test.fp > forsp.ir llc -march=x86 -filetype=obj --relocation-model=pic forsp.ir -O1 clang -c support.c -m32 -Os clang support.o forsp.ir.o -m32 -Os diff --git a/ast.cpp b/ast.cpp index 1de183e..3543ee1 100644 --- a/ast.cpp +++ b/ast.cpp @@ -17,14 +17,25 @@ */ #include "ast.hpp" +#include +#include + int ThunkAST::tcount = 0; NumberAST::NumberAST(const std::string& n): BaseAST(n) {} llvm::Value *NumberAST::codegen(LLVMState& llvmState) const { - auto val = llvmState.createInt(std::stoi(name)); - return llvmState.builder.CreateStore(val, llvmState.createPush()); + int value; + auto [ptr, _] = std::from_chars(&name.front(), &name.back() + 1, value); + + if (ptr <= &name.back()) { + std::cerr << "error: not a number: " << name << std::endl; + return nullptr; + } else { + auto val = llvmState.createInt(value); + return llvmState.builder.CreateStore(val, llvmState.createPush()); + } } PushAST::PushAST(const std::string& n): BaseAST(n) {} @@ -38,6 +49,7 @@ llvm::Value *PushAST::codegen(LLVMState& llvmState) const return llvmState.builder.CreateStore(var, dsget); } else { + std::cerr << "error: not defined: " << name << std::endl; return nullptr; } } @@ -68,6 +80,8 @@ llvm::Value *CallAST::codegen(LLVMState& llvmState) const return llvmState.builder.CreateCall(llvmState.ftype, cast); } } else { + std::cerr << "warning: anticipating external function: " + << name << std::endl; auto func = llvmState.createFunction(name); Var::addGlobal(name, Var {func, true}); return llvmState.builder.CreateCall(llvmState.ftype, func); diff --git a/llvm.cpp b/llvm.cpp index e5ed2db..f1ee27a 100644 --- a/llvm.cpp +++ b/llvm.cpp @@ -76,6 +76,5 @@ llvm::Constant *LLVMState::createInt(int n) void LLVMState::output() { - //std::cout << "LLVM:" << std::endl; - modul.print(llvm::errs(), nullptr); + modul.print(llvm::outs(), nullptr); } diff --git a/main.cpp b/main.cpp index f2c0b1d..a632c9b 100644 --- a/main.cpp +++ b/main.cpp @@ -40,14 +40,13 @@ int main() Var::pushScope(); std::string line; - while (std::cin.good()) { + for (unsigned lineno = 1; std::cin.good(); ++lineno) { std::getline(std::cin, line); - parseString(line); - //std::cout << std::endl; + if (!parseString(line)) + std::cerr << " at line " << lineno << std::endl; } llvmState.output(); - std::cout << std::endl; } @@ -56,11 +55,9 @@ bool parseString(std::string_view sv) do { const auto [nsv, tok] = nextToken(sv); - //printToken(tok); - if (tok == Token::none && !nsv.empty()) { - std::cerr << "unknown " << nsv << std::endl; - break; + std::cerr << "error: unknown term: " << nsv << std::endl; + return false; } else { std::unique_ptr expr; @@ -76,6 +73,8 @@ bool parseString(std::string_view sv) { auto& thunk = scope.back(); auto gen = thunk.codegen(llvmState); + if (!gen) + return false; Var::popScope(); Var::addLocal(thunk.name, Var {gen, true}); expr.reset(new PushAST {thunk.name}); @@ -83,7 +82,8 @@ bool parseString(std::string_view sv) } break; case Token::Quote: - break; + std::cerr << "error: quoting is not supported!" << std::endl; + return false; case Token::PopVar: expr.reset(new PopAST {name}); break; @@ -100,9 +100,14 @@ bool parseString(std::string_view sv) break; } - if (expr && !scope.empty()) { - expr->codegen(llvmState); - //scope.back().body.emplace_back().swap(expr); + if (expr) { + if (!scope.empty()) { + if (!expr->codegen(llvmState)) + return false; + } else if (tok != Token::ThunkClose) { + std::cerr << "error: non-thunk at top level!" << std::endl; + return false; + } } }