Skip to content

Commit dc6ef49

Browse files
committed
Add CodeType enum
There are 3 types of compiled code: script (void), reporter (any value), hat predicate (bool)
1 parent fdcede5 commit dc6ef49

15 files changed

+105
-63
lines changed

include/scratchcpp/compiler.h

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,13 @@ class LIBSCRATCHCPP_EXPORT Compiler
3838
Unknown
3939
};
4040

41+
enum class CodeType
42+
{
43+
Script,
44+
Reporter,
45+
HatPredicate
46+
};
47+
4148
using ArgTypes = std::vector<StaticType>;
4249
using Args = std::vector<CompilerValue *>;
4350

@@ -49,7 +56,7 @@ class LIBSCRATCHCPP_EXPORT Compiler
4956
Target *target() const;
5057
std::shared_ptr<Block> block() const;
5158

52-
std::shared_ptr<ExecutableCode> compile(std::shared_ptr<Block> startBlock, bool isHatPredicate = false);
59+
std::shared_ptr<ExecutableCode> compile(std::shared_ptr<Block> startBlock, CodeType codeType = CodeType::Script);
5360
void preoptimize();
5461

5562
CompilerValue *addFunctionCall(const std::string &functionName, StaticType returnType = StaticType::Void, const ArgTypes &argTypes = {}, const Args &args = {});

src/engine/compiler.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ std::shared_ptr<libscratchcpp::Block> Compiler::block() const
4444
}
4545

4646
/*! Compiles the script starting with the given block. */
47-
std::shared_ptr<ExecutableCode> Compiler::compile(std::shared_ptr<Block> startBlock, bool isHatPredicate)
47+
std::shared_ptr<ExecutableCode> Compiler::compile(std::shared_ptr<Block> startBlock, CodeType codeType)
4848
{
4949
BlockPrototype *procedurePrototype = nullptr;
5050

@@ -60,14 +60,14 @@ std::shared_ptr<ExecutableCode> Compiler::compile(std::shared_ptr<Block> startBl
6060
}
6161
}
6262

63-
impl->builder = impl->builderFactory->create(impl->ctx, procedurePrototype, isHatPredicate);
63+
impl->builder = impl->builderFactory->create(impl->ctx, procedurePrototype, codeType);
6464
impl->substackTree.clear();
6565
impl->substackHit = false;
6666
impl->emptySubstack = false;
6767
impl->warp = false;
6868
impl->block = startBlock;
6969

70-
if (impl->block && isHatPredicate) {
70+
if (impl->block && codeType == CodeType::HatPredicate) {
7171
auto f = impl->block->hatPredicateCompileFunction();
7272

7373
if (f) {

src/engine/internal/codebuilderfactory.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,10 @@ std::shared_ptr<CodeBuilderFactory> CodeBuilderFactory::instance()
1313
return m_instance;
1414
}
1515

16-
std::shared_ptr<ICodeBuilder> CodeBuilderFactory::create(CompilerContext *ctx, BlockPrototype *procedurePrototype, bool isPredicate) const
16+
std::shared_ptr<ICodeBuilder> CodeBuilderFactory::create(CompilerContext *ctx, BlockPrototype *procedurePrototype, Compiler::CodeType codeType) const
1717
{
1818
assert(dynamic_cast<LLVMCompilerContext *>(ctx));
19-
return std::make_shared<LLVMCodeBuilder>(static_cast<LLVMCompilerContext *>(ctx), procedurePrototype, isPredicate);
19+
return std::make_shared<LLVMCodeBuilder>(static_cast<LLVMCompilerContext *>(ctx), procedurePrototype, codeType);
2020
}
2121

2222
std::shared_ptr<CompilerContext> CodeBuilderFactory::createCtx(IEngine *engine, Target *target) const

src/engine/internal/codebuilderfactory.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ class CodeBuilderFactory : public ICodeBuilderFactory
1111
{
1212
public:
1313
static std::shared_ptr<CodeBuilderFactory> instance();
14-
std::shared_ptr<ICodeBuilder> create(CompilerContext *ctx, BlockPrototype *procedurePrototype, bool isPredicate) const override;
14+
std::shared_ptr<ICodeBuilder> create(CompilerContext *ctx, BlockPrototype *procedurePrototype, Compiler::CodeType codeType) const override;
1515
std::shared_ptr<CompilerContext> createCtx(IEngine *engine, Target *target) const override;
1616

1717
private:

src/engine/internal/engine.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -276,7 +276,7 @@ void Engine::compile()
276276
script->setCode(compiler.compile(block));
277277

278278
if (block->hatPredicateCompileFunction())
279-
script->setHatPredicateCode(compiler.compile(block, true));
279+
script->setHatPredicateCode(compiler.compile(block, Compiler::CodeType::HatPredicate));
280280
} else {
281281
std::cout << "warning: unsupported top level block: " << block->opcode() << std::endl;
282282
m_unsupportedBlocks.insert(block->opcode());

src/engine/internal/icodebuilderfactory.h

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,23 +2,20 @@
22

33
#pragma once
44

5+
#include <scratchcpp/compiler.h>
56
#include <memory>
67

78
namespace libscratchcpp
89
{
910

1011
class ICodeBuilder;
11-
class CompilerContext;
12-
class BlockPrototype;
13-
class Target;
14-
class IEngine;
1512

1613
class ICodeBuilderFactory
1714
{
1815
public:
1916
virtual ~ICodeBuilderFactory() { }
2017

21-
virtual std::shared_ptr<ICodeBuilder> create(CompilerContext *ctx, BlockPrototype *procedurePrototype = nullptr, bool isPredicate = false) const = 0;
18+
virtual std::shared_ptr<ICodeBuilder> create(CompilerContext *ctx, BlockPrototype *procedurePrototype = nullptr, Compiler::CodeType codeType = Compiler::CodeType::Script) const = 0;
2219
virtual std::shared_ptr<CompilerContext> createCtx(IEngine *engine, Target *target) const = 0;
2320
};
2421

src/engine/internal/llvm/llvmcodebuilder.cpp

Lines changed: 47 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ static std::unordered_map<ValueType, Compiler::StaticType>
2626
static const std::unordered_set<LLVMInstruction::Type>
2727
VAR_LIST_READ_INSTRUCTIONS = { LLVMInstruction::Type::ReadVariable, LLVMInstruction::Type::GetListItem, LLVMInstruction::Type::GetListItemIndex, LLVMInstruction::Type::ListContainsItem };
2828

29-
LLVMCodeBuilder::LLVMCodeBuilder(LLVMCompilerContext *ctx, BlockPrototype *procedurePrototype, bool isPredicate) :
29+
LLVMCodeBuilder::LLVMCodeBuilder(LLVMCompilerContext *ctx, BlockPrototype *procedurePrototype, Compiler::CodeType codeType) :
3030
m_ctx(ctx),
3131
m_target(ctx->target()),
3232
m_llvmCtx(*ctx->llvmCtx()),
@@ -35,7 +35,7 @@ LLVMCodeBuilder::LLVMCodeBuilder(LLVMCompilerContext *ctx, BlockPrototype *proce
3535
m_procedurePrototype(procedurePrototype),
3636
m_defaultWarp(procedurePrototype ? procedurePrototype->warp() : false),
3737
m_warp(m_defaultWarp),
38-
m_isPredicate(isPredicate)
38+
m_codeType(codeType)
3939
{
4040
initTypes();
4141
createVariableMap();
@@ -56,8 +56,8 @@ std::shared_ptr<ExecutableCode> LLVMCodeBuilder::finalize()
5656
if (it == m_instructions.end())
5757
m_warp = true;
5858

59-
// Do not create coroutine in hat predicates
60-
if (m_isPredicate)
59+
// Only create coroutines in scripts
60+
if (m_codeType != Compiler::CodeType::Script)
6161
m_warp = true;
6262
}
6363

@@ -1319,15 +1319,20 @@ std::shared_ptr<ExecutableCode> LLVMCodeBuilder::finalize()
13191319
// End and verify the function
13201320
llvm::PointerType *pointerType = llvm::PointerType::get(llvm::Type::getInt8Ty(m_llvmCtx), 0);
13211321

1322-
if (m_isPredicate) {
1323-
// Use last instruction return value
1324-
assert(!m_instructions.empty());
1325-
m_builder.CreateRet(m_instructions.back()->functionReturnReg->value);
1326-
} else {
1327-
if (m_warp)
1328-
m_builder.CreateRet(llvm::ConstantPointerNull::get(pointerType));
1329-
else
1330-
coro->end();
1322+
switch (m_codeType) {
1323+
case Compiler::CodeType::Script:
1324+
if (m_warp)
1325+
m_builder.CreateRet(llvm::ConstantPointerNull::get(pointerType));
1326+
else
1327+
coro->end();
1328+
break;
1329+
1330+
// TODO: Implement reporter code type
1331+
case Compiler::CodeType::HatPredicate:
1332+
// Use last instruction return value
1333+
assert(!m_instructions.empty());
1334+
m_builder.CreateRet(m_instructions.back()->functionReturnReg->value);
1335+
break;
13311336
}
13321337

13331338
verifyFunction(m_function);
@@ -1349,7 +1354,7 @@ std::shared_ptr<ExecutableCode> LLVMCodeBuilder::finalize()
13491354

13501355
verifyFunction(resumeFunc);
13511356

1352-
return std::make_shared<LLVMExecutableCode>(m_ctx, m_function->getName().str(), resumeFunc->getName().str(), m_isPredicate);
1357+
return std::make_shared<LLVMExecutableCode>(m_ctx, m_function->getName().str(), resumeFunc->getName().str(), m_codeType);
13531358
}
13541359

13551360
CompilerValue *LLVMCodeBuilder::addFunctionCall(const std::string &functionName, Compiler::StaticType returnType, const Compiler::ArgTypes &argTypes, const Compiler::Args &args)
@@ -2019,7 +2024,20 @@ void LLVMCodeBuilder::popLoopScope()
20192024

20202025
std::string LLVMCodeBuilder::getMainFunctionName(BlockPrototype *procedurePrototype)
20212026
{
2022-
return procedurePrototype ? "proc." + procedurePrototype->procCode() : (m_isPredicate ? "predicate" : "script");
2027+
std::string name;
2028+
2029+
switch (m_codeType) {
2030+
case Compiler::CodeType::Script:
2031+
name = "script";
2032+
break;
2033+
2034+
// TODO: Implement reporter code type
2035+
case Compiler::CodeType::HatPredicate:
2036+
name = "predicate";
2037+
break;
2038+
}
2039+
2040+
return procedurePrototype ? "proc." + procedurePrototype->procCode() : name;
20232041
}
20242042

20252043
std::string LLVMCodeBuilder::getResumeFunctionName(BlockPrototype *procedurePrototype)
@@ -2046,7 +2064,20 @@ llvm::FunctionType *LLVMCodeBuilder::getMainFunctionType(BlockPrototype *procedu
20462064
}
20472065
}
20482066

2049-
return llvm::FunctionType::get(m_isPredicate ? m_builder.getInt1Ty() : pointerType, argTypes, false);
2067+
llvm::Type *retType = nullptr;
2068+
2069+
switch (m_codeType) {
2070+
case Compiler::CodeType::Script:
2071+
retType = pointerType;
2072+
break;
2073+
2074+
// TODO: Implement reporter code type
2075+
case Compiler::CodeType::HatPredicate:
2076+
retType = m_builder.getInt1Ty();
2077+
break;
2078+
}
2079+
2080+
return llvm::FunctionType::get(retType, argTypes, false);
20502081
}
20512082

20522083
llvm::Function *LLVMCodeBuilder::getOrCreateFunction(const std::string &name, llvm::FunctionType *type)

src/engine/internal/llvm/llvmcodebuilder.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ class LLVMLoopScope;
2525
class LLVMCodeBuilder : public ICodeBuilder
2626
{
2727
public:
28-
LLVMCodeBuilder(LLVMCompilerContext *ctx, BlockPrototype *procedurePrototype = nullptr, bool isPredicate = false);
28+
LLVMCodeBuilder(LLVMCompilerContext *ctx, BlockPrototype *procedurePrototype = nullptr, Compiler::CodeType codeType = Compiler::CodeType::Script);
2929

3030
std::shared_ptr<ExecutableCode> finalize() override;
3131

@@ -239,7 +239,7 @@ class LLVMCodeBuilder : public ICodeBuilder
239239
bool m_defaultWarp = false;
240240
bool m_warp = false;
241241
int m_defaultArgCount = 0;
242-
bool m_isPredicate = false; // for hat predicates
242+
Compiler::CodeType m_codeType = Compiler::CodeType::Script;
243243

244244
long m_loopScope = -1; // index
245245
std::vector<std::shared_ptr<LLVMLoopScope>> m_loopScopes;

src/engine/internal/llvm/llvmexecutablecode.cpp

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,11 @@
1616

1717
using namespace libscratchcpp;
1818

19-
LLVMExecutableCode::LLVMExecutableCode(LLVMCompilerContext *ctx, const std::string &mainFunctionName, const std::string &resumeFunctionName, bool isPredicate) :
19+
LLVMExecutableCode::LLVMExecutableCode(LLVMCompilerContext *ctx, const std::string &mainFunctionName, const std::string &resumeFunctionName, Compiler::CodeType codeType) :
2020
m_ctx(ctx),
2121
m_mainFunctionName(mainFunctionName),
2222
m_resumeFunctionName(resumeFunctionName),
23-
m_isPredicate(isPredicate)
23+
m_codeType(codeType)
2424
{
2525
assert(m_ctx);
2626

@@ -101,10 +101,16 @@ std::shared_ptr<ExecutionContext> LLVMExecutableCode::createExecutionContext(Thr
101101
if (!m_ctx->jitInitialized())
102102
m_ctx->initJit();
103103

104-
if (m_isPredicate)
105-
m_mainFunction = m_ctx->lookupFunction<PredicateFunctionType>(m_mainFunctionName);
106-
else
107-
m_mainFunction = m_ctx->lookupFunction<MainFunctionType>(m_mainFunctionName);
104+
switch (m_codeType) {
105+
case Compiler::CodeType::Script:
106+
m_mainFunction = m_ctx->lookupFunction<MainFunctionType>(m_mainFunctionName);
107+
break;
108+
109+
// TODO: Implement reporter code type
110+
case Compiler::CodeType::HatPredicate:
111+
m_mainFunction = m_ctx->lookupFunction<PredicateFunctionType>(m_mainFunctionName);
112+
break;
113+
}
108114

109115
m_resumeFunction = m_ctx->lookupFunction<ResumeFunctionType>(m_resumeFunctionName);
110116
return std::make_shared<LLVMExecutionContext>(thread);

src/engine/internal/llvm/llvmexecutablecode.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
#pragma once
44

55
#include <scratchcpp/executablecode.h>
6+
#include <scratchcpp/compiler.h>
67
#include <scratchcpp/valuedata.h>
78
#include <llvm/IR/LLVMContext.h>
89

@@ -16,7 +17,7 @@ class LLVMExecutionContext;
1617
class LLVMExecutableCode : public ExecutableCode
1718
{
1819
public:
19-
LLVMExecutableCode(LLVMCompilerContext *ctx, const std::string &mainFunctionName, const std::string &resumeFunctionName, bool isPredicate);
20+
LLVMExecutableCode(LLVMCompilerContext *ctx, const std::string &mainFunctionName, const std::string &resumeFunctionName, Compiler::CodeType codeType);
2021

2122
void run(ExecutionContext *context) override;
2223
bool runPredicate(ExecutionContext *context) override;
@@ -38,7 +39,7 @@ class LLVMExecutableCode : public ExecutableCode
3839
std::string m_mainFunctionName;
3940
std::string m_predicateFunctionName;
4041
std::string m_resumeFunctionName;
41-
bool m_isPredicate = false;
42+
Compiler::CodeType m_codeType;
4243

4344
mutable std::variant<MainFunctionType, PredicateFunctionType> m_mainFunction;
4445
mutable ResumeFunctionType m_resumeFunction = nullptr;

0 commit comments

Comments
 (0)