Skip to content

Commit

Permalink
VM: add support for appending arrays
Browse files Browse the repository at this point in the history
  • Loading branch information
mrunix00 committed Jul 31, 2024
1 parent 829d290 commit b95717a
Show file tree
Hide file tree
Showing 5 changed files with 38 additions and 6 deletions.
1 change: 1 addition & 0 deletions include/utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
throw std::runtime_error("[Node::compile] Identifier not found: " + identifier); \
} \
switch (type->type) { \
case VariableType::Type::Array: \
case VariableType::Type::Object: \
instruction.type = isLocal ? Instruction::InstructionType::OPERATION##LocalObject \
: Instruction::InstructionType::OPERATION##GlobalObject; \
Expand Down
3 changes: 2 additions & 1 deletion include/vm.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ struct Instruction {
MakeArray,
LoadFromLocalArray,
LoadFromGlobalArray,
AppendToArray,
Return,
Call,
JumpIfFalse,
Expand Down Expand Up @@ -69,7 +70,7 @@ struct FunctionType : public VariableType {
};
struct ArrayObjectType : public VariableType {
VariableType *elementType;
explicit ArrayObjectType(VariableType *elementType) : VariableType(Object), elementType(elementType){};
explicit ArrayObjectType(VariableType *elementType) : VariableType(Array), elementType(elementType){};
};

struct Object {
Expand Down
13 changes: 9 additions & 4 deletions src/ast.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,23 +61,28 @@ void BinaryExpression::compile(Program &program, Segment &segment) const {
emitStore(program, segment, dynamic_cast<Node &>(*left).token.value);
return;
}
if (op.type == IncrementAssign || op.type == DecrementAssign) {
if ((op.type == IncrementAssign || op.type == DecrementAssign) &&
left->nodeType == AbstractSyntaxTree::Type::Node) {
auto node = dynamic_cast<Node *>(left);
if (node->token.type != Identifier)
throw std::runtime_error("[BinaryExpression::compile] Invalid expression varType!");
auto varType = segment.find_local(node->token.value) != -1 ? segment.locals[node->token.value].type : program.segments[0].locals[node->token.value].type;
auto varType = segment.find_local(node->token.value) != -1 ? segment.locals[node->token.value] : program.segments[0].locals[node->token.value];
emitLoad(program, segment, node->token.value);
right->compile(program, segment);
switch (op.type) {
case IncrementAssign:
switch (varType->type) {
switch (varType.type->type) {
VAR_CASE(Add, I64)
case VariableType::Array: {
left->compile(program, segment);
segment.instructions.push_back({.type = Instruction::AppendToArray});
} break;
default:
throw std::runtime_error("[BinaryExpression::compile] Invalid varType!");
}
break;
case DecrementAssign:
switch (varType->type) {
switch (varType.type->type) {
VAR_CASE(Sub, I64)
default:
throw std::runtime_error("[BinaryExpression::compile] Invalid varType!");
Expand Down
16 changes: 15 additions & 1 deletion src/vm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -232,7 +232,10 @@ void VM::run(const Program &program) {
pushStack(std::bit_cast<uint64_t>(instruction.params.ptr));
} break;
case Instruction::MakeArray: {
auto data = new uint64_t[instruction.params.index];
auto data = (uint64_t *) malloc(instruction.params.index * sizeof(uint64_t));
if (data == nullptr) {
throw std::runtime_error("Memory allocation failure!");
}
for (size_t i = instruction.params.index - 1; i != -1; i--) {
auto val = popStack();
data[i] = val;
Expand All @@ -256,6 +259,17 @@ void VM::run(const Program &program) {
}
pushStack(array->data[index]);
} break;
case Instruction::AppendToArray: {
auto array = std::bit_cast<ArrayObject *>(popStack());
auto val = popStack();
auto data = (uint64_t*) realloc(array->data, (array->size + 1) * sizeof(uint64_t));
if (data == nullptr) {
throw std::runtime_error("Memory allocation failure!");
}
array->data = data;
array->data[array->size++] = val;
pushStack(std::bit_cast<uint64_t>(array));
} break;
case Instruction::Exit:
return;
}
Expand Down
11 changes: 11 additions & 0 deletions tests/vm_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -243,3 +243,14 @@ TEST(VM, ArrayAccess) {
vm.run(program);
ASSERT_EQ(vm.topStack(), 3);
}

TEST(VM, AppendToArray){
const char *input = "define x : int[] = [1, 2, 3, 4];"
"x += 5;"
"x;";
VM vm;
auto program = compile(input);
vm.run(program);
auto obj = reinterpret_cast<ArrayObject *>(vm.topStack());
ASSERT_EQ(*obj, std::vector<uint64_t>({1, 2, 3, 4, 5}));
}

0 comments on commit b95717a

Please sign in to comment.