Skip to content

Commit

Permalink
feat(vm): generate and use copy constructors for each type.
Browse files Browse the repository at this point in the history
  • Loading branch information
PoetaKodu committed Jul 24, 2022
1 parent e4d6b7c commit ea54c96
Show file tree
Hide file tree
Showing 24 changed files with 512 additions and 124 deletions.
2 changes: 1 addition & 1 deletion VM/include/RigCVM/Functions.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ struct Function
using RuntimeFn = FunctionInstance;
using RawFnSign = OptValue(Instance&, ArgSpan);
using RawFn = std::function<RawFnSign>;
using ReturnType = std::optional<DeclType>;
using ReturnType = DeclType;

using Impl = ExtendedVariant<
RuntimeFn,
Expand Down
23 changes: 20 additions & 3 deletions VM/include/RigCVM/Scope.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,18 +21,24 @@ auto findOverload(
FunctionCandidates const& funcs_,
FunctionParamTypeSpan paramTypes_,
bool method_ = false,
Function::ReturnType returnType_ = std::nullopt
Function::ReturnType returnType_ = nullptr
) -> Function const*;

auto findOverload(
FunctionOverloads const& overloads_,
FunctionParamTypeSpan paramTypes_,
bool method_ = false,
Function::ReturnType returnType_ = std::nullopt
Function::ReturnType returnType_ = nullptr
) -> Function const*;

using TemplateParameters = std::map<std::string, TypeConstraint, std::less<> >;

template <typename T>
struct ScopeTraceResult {
Scope const* scope;
T value;
};

struct Scope
{
Scope(Instance& vm_)
Expand All @@ -49,6 +55,11 @@ struct Scope
Function const* func = nullptr;

Scope* parent = nullptr;
void* addr = nullptr;

#if DEBUG
std::string name = "";
#endif

// Currently unused
std::map<IType*, Impls*> impls;
Expand Down Expand Up @@ -98,6 +109,12 @@ struct Scope
/// </summary>
auto findType(std::string_view typeName_) const -> IType const*;

/// <summary>
/// Returns type with name `typeName_`,
/// or `nullptr` if no such type exist within this or one of parent scopes.
/// </summary>
auto traceForType(std::string_view typeName_) const -> Opt< ScopeTraceResult<IType const*> >;

/// <summary>
/// Returns operator overload with name `opName_` and type `type_`,
/// or `nullptr` if no such operator exist within this scope.
Expand Down Expand Up @@ -128,5 +145,5 @@ struct Scope
auto registerOperator(Instance& vm_, std::string_view name_, Operator::Type type_, Function func_) -> Function&;
};

std::unique_ptr<Scope> makeUniverseScope(Instance &vm_);
auto setupUniverseScope(Instance &vm_, Scope& scope_) -> void;
}
2 changes: 2 additions & 0 deletions VM/include/RigCVM/TypeSystem/ArrayType.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ namespace rigc::vm

struct ArrayType : TemplateType
{
using Super = TemplateType;

ArrayType() = default;
ArrayType(InnerType inner_, size_t size_)
:
Expand Down
7 changes: 6 additions & 1 deletion VM/include/RigCVM/TypeSystem/ClassType.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,16 @@ namespace rigc::vm
class ClassType : public StructuralType
{
public:
using Super = StructuralType;

Vec< DataMember > dataMembers;

auto defaultConstructor() const -> Function*;
auto constructors() const -> FunctionOverloads const*;

auto add(DataMember mem, ParserNode const* initExpr) -> void;

auto postInitialize(Instance& vm_) -> void override;

auto postEvaluate(Instance& vm_) -> void;
};
}
2 changes: 2 additions & 0 deletions VM/include/RigCVM/TypeSystem/EnumType.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ namespace rigc::vm
class EnumType : public StructuralType
{
public:
using Super = StructuralType;

DeclType underlyingType;
std::unordered_map<std::string, Value> fields;

Expand Down
2 changes: 2 additions & 0 deletions VM/include/RigCVM/TypeSystem/FuncType.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ namespace rigc::vm
//todo: refactor maybe use template?
struct FuncType : IType
{
using Super = IType;

InnerType result;
std::vector<InnerType> parameters;

Expand Down
6 changes: 5 additions & 1 deletion VM/include/RigCVM/TypeSystem/IType.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ using MutDeclType = MutInnerType;
using TemplateArgument = ExtendedVariant<int, DeclType>; // int as a placeholder
using TemplateArguments = std::map<std::string, TemplateArgument, std::less<>>;

using FunctionOverloads = std::vector<Function*>;

/// <summary>
/// An interface for each type.
/// </summary>
Expand Down Expand Up @@ -97,7 +99,9 @@ struct IType : public std::enable_shared_from_this<IType>
return EmptyTemplateArguments;
}

virtual auto postInitialize(Instance& vm_) -> void {}
auto constructors() const -> FunctionOverloads const*;

virtual auto postInitialize(Instance& vm_) -> void;
};

template <typename T>
Expand Down
8 changes: 6 additions & 2 deletions VM/include/RigCVM/TypeSystem/RefType.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@ namespace rigc::vm
{
struct RefType : TemplateType
{
using TemplateType::TemplateType;
using Super = TemplateType;

using Super::Super;

auto inner() const -> DeclType { return args.front().as<DeclType>(); }

Expand Down Expand Up @@ -39,7 +41,9 @@ struct RefType : TemplateType

struct AddrType : TemplateType
{
using TemplateType::TemplateType;
using Super = TemplateType;

using Super::Super;

auto inner() const { return args.front().as<DeclType>(); }

Expand Down
12 changes: 9 additions & 3 deletions VM/include/RigCVM/VM.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ struct Instance
/// <summary>Returns the "self" reference in method context.</summary>
auto getSelf() -> Value;

auto evaluateType(rigc::ParserNode const& typeNode_) -> DeclType;
auto evaluateType(rigc::ParserNode const& typeNode_, Scope* scope_ = nullptr) -> DeclType;

auto findVariableByName(std::string_view name_) -> OptValue;
auto findType(std::string_view name_) -> IType const*;
Expand All @@ -50,12 +50,18 @@ struct Instance

auto cloneValue(Value value_) -> Value;

auto extendReturnValueLifetime(Value value_) -> void;

/// Address is related to the code block memory obtained from a parser.
auto scopeOf(void const *addr_) -> Scope&;

/// Pushes the stack frame for specified address that is used to acquire a scope.
/// Address is related to the code block memory obtained from a parser.
#if DEBUG
auto pushStackFrameOf(void const* addr_, std::string name = "") -> Scope&;
#else
auto pushStackFrameOf(void const* addr_) -> Scope&;
#endif

/// Pops current stack frame
auto popStackFrame() -> void;
Expand Down Expand Up @@ -120,7 +126,7 @@ struct Instance
FunctionInstance const* currentFunc = nullptr;

/// Currently parsed class type.
StructuralType* currentClass = nullptr;
StructuralType* currentClass = nullptr;

/// Currently executed method's class.
ClassType const* classContext = nullptr;
Expand All @@ -129,7 +135,7 @@ struct Instance
bool returnTriggered = false;

/// The level of loop breakage triggered by `break <number>;` or `break;`
int breakLevel = 0;
int breakLevel = 0;

/// Whether currently executed loop has triggered a return statement.
bool continueTriggered = false;
Expand Down
6 changes: 4 additions & 2 deletions VM/src/Executors/All.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -63,8 +63,8 @@ auto executeCodeBlock(Instance &vm_, rigc::ParserNode const& codeBlock_) -> OptV
{
auto stackFramePos = vm_.stack.size;
OptValue val = vm_.evaluate(*stmt);
if (stmt->is_type<rigc::Expression>())
vm_.stack.size = stackFramePos;
// if (stmt->is_type<rigc::Expression>())
// vm_.stack.size = stackFramePos;

if (vm_.returnTriggered)
return val;
Expand Down Expand Up @@ -307,6 +307,8 @@ auto evaluateClassDefinition(Instance &vm_, rigc::ParserNode const& expr_) -> Op
vm_.evaluate(*child);
}

type->postEvaluate(vm_);

vm_.currentClass = prevClass;

return {};
Expand Down
24 changes: 18 additions & 6 deletions VM/src/Executors/ExpressionExecutor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -422,7 +422,8 @@ auto ExpressionExecutor::evalPostfixOperator(rigc::ParserNode const& op_, Action
if (auto act = lhs_.as<PendingAction>(); isSymbol(*act))
{
autoOverloadResolution = true;
candidates = vm.findFunction(findElem<rigc::Name>(*act)->string_view());
auto symbolName = findElem<rigc::Name>(*act)->string_view();
candidates = vm.findFunction(symbolName);
}
}
else if (auto act = lhs_.as<ProcessedAction>(); act.is<ProcessedFunction>())
Expand Down Expand Up @@ -454,7 +455,7 @@ auto ExpressionExecutor::evalPostfixOperator(rigc::ParserNode const& op_, Action
candidates.push_back( { &vm.scopeOf(nullptr), funcVal.view<FunctionOverloads const*>() } );
}

if (self)
if (self)
{
evaluatedArgs[0] = vm.allocateReference(*self);
paramTypes[0] = evaluatedArgs[0].type;
Expand Down Expand Up @@ -501,14 +502,21 @@ auto ExpressionExecutor::evalPostfixOperator(rigc::ParserNode const& op_, Action
//
if (!fn) {
std::string paramsString;
for(size_t i = 0; i < numParams; ++i)
size_t paramNumber = 0;
for(size_t i = 0; paramNumber < numParams; ++i)
{
if (i > 0)
if (i == 0 && !paramTypes[i])
continue;
if (paramNumber > 0)
paramsString += ", ";
paramsString += paramTypes[i]->name();
++paramNumber;
}

throw RigCError("Not matching function to call with params: {}.", paramsString)
throw RigCError("Not matching function {}to call with arguments of type: {}.",
fnName.empty() ? "" : fmt::format("\"{}\" ", fnName),
paramsString
)
.withHelp("Check the function name and arguments' arity and types.")
.withLine(vm.lastEvaluatedLine);
}
Expand All @@ -519,9 +527,13 @@ auto ExpressionExecutor::evalPostfixOperator(rigc::ParserNode const& op_, Action
{
constructor = true;
paramTypes[0] = fn->outerType->shared_from_this();
self = vm.allocateReference(vm.allocateOnStack(paramTypes[0], nullptr));
self = vm.allocateReference(vm.allocateOnStack(paramTypes[0], nullptr, 0));
evaluatedArgs[0] = *self;
++numParams;
// fmt::print("> Constructed value of type {} is at {}\n", paramTypes[0]->name(), self->removeRef().data);
// fmt::print("> Constructed reference of type {} is at {}\n", self->type->name(), self->data);
// fmt::print("> Constructed reference points at {}\n", self->view<void*>());
// fmt::print("> Its ref size: {} bytes\n", self->type->size());
}

auto result = vm.executeFunction(*fn, viewArray( evaluatedArgs, (self ? 0 : 1), numParams) );
Expand Down
12 changes: 6 additions & 6 deletions VM/src/Executors/FlowControl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ auto executeIfStatement(Instance &vm_, rigc::ParserNode const& stmt_) -> OptValu

auto result = vm_.evaluate(expr);

if (result.has_value() && result.value().view<bool>() == true)
if (result.has_value() && result->safeRemoveRef().view<bool>() == true)
{
auto ret = vm_.evaluate(*body);
if (vm_.returnTriggered)
Expand Down Expand Up @@ -88,7 +88,7 @@ auto executeWhileStatement(Instance &vm_, rigc::ParserNode const& stmt_) -> OptV

auto result = vm_.evaluate(expr);

if (result.has_value() && result.value().view<bool>())
if (result.has_value() && result->safeRemoveRef().view<bool>())
{
auto ret = vm_.evaluate(*body);

Expand Down Expand Up @@ -127,22 +127,22 @@ auto executeForStatement(Instance &vm_, rigc::ParserNode const& stmt_) -> OptVal
auto scope = StackFramePusher(vm_, *body);
auto const conditionResult = vm_.evaluate(conditionExpr);

if (conditionResult.has_value() && conditionResult.value().view<bool>())
if (conditionResult.has_value() && conditionResult->safeRemoveRef().view<bool>())
{
auto ret = vm_.evaluate(*body);

if (vm_.returnTriggered) return ret;
}
else
break;

vm_.evaluate(incrementExpr);
if(vm_.breakLevel)
if(vm_.breakLevel)
{
vm_.breakLevel--;
break;
}
else if(vm_.continueTriggered)
else if(vm_.continueTriggered)
{
vm_.continueTriggered = false;
continue;
Expand Down
Loading

0 comments on commit ea54c96

Please sign in to comment.