diff --git a/src/parsers/epsilon.c b/src/parsers/epsilon.c index bb6e8beb31cca3ff09a565171b4e554e07f2ffad..4c5abc406a390b3fce592a6b041bca5518ebb0ae 100644 --- a/src/parsers/epsilon.c +++ b/src/parsers/epsilon.c @@ -1,3 +1,10 @@ +#ifdef HAMMER_LLVM_BACKEND +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wpedantic" +#include <llvm-c/Core.h> +#pragma GCC diagnostic pop +#include "../backends/llvm/llvm.h" +#endif #include "parser_internal.h" static HParseResult* parse_epsilon(void* env, HParseState* state) { @@ -12,12 +19,45 @@ static bool epsilon_ctrvm(HRVMProg *prog, void* env) { return true; } +#ifdef HAMMER_LLVM_BACKEND + +static bool epsilon_llvm(HLLVMParserCompileContext *ctxt, void* env) { + if (!ctxt) return false; + + LLVMBasicBlockRef epsilon_bb = LLVMAppendBasicBlock(ctxt->func, "epsilon"); + + /* Basic block: epsilon */ + LLVMBuildBr(ctxt->builder, epsilon_bb); + LLVMPositionBuilderAtEnd(ctxt->builder, epsilon_bb); + + /* + * For epsilon we make a null-token parse result like with end, but we + * do it unconditionally. + */ + LLVMValueRef make_result_args[] = { + ctxt->arena, + LLVMConstNull(ctxt->llvm_parsedtokenptr) + }; + LLVMValueRef result_ptr = LLVMBuildCall(ctxt->builder, + LLVMGetNamedFunction(ctxt->mod, "make_result"), + make_result_args, 2, "result_ptr"); + /* Return it */ + LLVMBuildRet(ctxt->builder, result_ptr); + + return true; +} + +#endif + static const HParserVtable epsilon_vt = { .parse = parse_epsilon, .isValidRegular = h_true, .isValidCF = h_true, .desugar = desugar_epsilon, .compile_to_rvm = epsilon_ctrvm, +#ifdef HAMMER_LLVM_BACKEND + .llvm = epsilon_llvm, +#endif .higher = false, };