Skip to content

Commit

Permalink
VM: initialize variables with zero
Browse files Browse the repository at this point in the history
  • Loading branch information
mrunix00 committed Jul 9, 2024
1 parent 72cb23d commit 0e17234
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 40 deletions.
45 changes: 22 additions & 23 deletions include/utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,29 +40,28 @@
GENERATE_EMIT_FUNCTION(Load)
GENERATE_EMIT_FUNCTION(Store)

#define DECLARE_NUMBER_VAR(TYPE, PARAM) \
case TYPE: { \
segment.instructions.push_back({.type = Instruction::InstructionType::Load##TYPE, \
.params = {.PARAM = std::stoi(initNode->token.value)}}); \
segment.instructions.push_back({ \
.type = segment.id == 0 \
? Instruction::InstructionType::StoreGlobal##TYPE \
: Instruction::InstructionType::StoreLocal##TYPE, \
.params = {.index = segment.locals.size()}, \
}); \
segment.declare_variable(identifier.token.value, Variable::Type::TYPE); \
} break;

#define DECLARE_OTHER_VAR(TYPE) \
case TYPE: { \
initNode->compile(program, segment); \
segment.instructions.push_back({ \
.type = segment.id == 0 \
? Instruction::InstructionType::StoreGlobal##TYPE \
: Instruction::InstructionType::StoreLocal##TYPE, \
.params = {.index = segment.locals.size()}, \
}); \
segment.declare_variable(identifier.token.value, Variable::Type::TYPE); \
#define DECLARE_VAR_CASE(TYPE, PARAM) \
case TYPE: { \
if (!value.has_value()) { \
segment.instructions.push_back({ \
.type = Instruction::InstructionType::Load##TYPE, \
.params = {.PARAM = 0}, \
}); \
} else if (((Node *) value.value())->token.type == Number) { \
segment.instructions.push_back({ \
.type = Instruction::InstructionType::Load##TYPE, \
.params = {.PARAM = std::stoi(((Node *) value.value())->token.value)}, \
}); \
} else { \
((Node *) value.value())->compile(program, segment); \
} \
segment.instructions.push_back({ \
.type = segment.id == 0 \
? Instruction::InstructionType::StoreGlobal##TYPE \
: Instruction::InstructionType::StoreLocal##TYPE, \
.params = {.index = segment.locals.size()}, \
}); \
segment.declare_variable(identifier.token.value, Variable::Type::TYPE); \
} break;

#define VAR_CASE(OP, TYPE) \
Expand Down
23 changes: 6 additions & 17 deletions src/ast.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -129,22 +129,11 @@ void Declaration::compile(Program &program, Segment &segment) const {
}
switch (type.value()->nodeType) {
case AbstractSyntaxTree::Type::Node: {
Node *initNode = (Node *) value.value();
Node *typeNode = (Node *) type.value();
if (initNode->token.type == Number) {
switch (typeNode->token.type) {
DECLARE_NUMBER_VAR(I32, i32)
DECLARE_NUMBER_VAR(I64, i64)
default:
throw std::runtime_error("[Declaration::compile] Unimplemented type handler!");
}
} else {
switch (typeNode->token.type) {
DECLARE_OTHER_VAR(I32)
DECLARE_OTHER_VAR(I64)
default:
throw std::runtime_error("[Declaration::compile] Unimplemented type handler!");
}
switch (((Node *) type.value())->token.type) {
DECLARE_VAR_CASE(I32, i32)
DECLARE_VAR_CASE(I64, i64)
default:
throw std::runtime_error("[Declaration::compile] Unimplemented type handler!");
}
} break;
case AbstractSyntaxTree::Type::FunctionDeclaration: {
Expand All @@ -163,7 +152,7 @@ void Declaration::compile(Program &program, Segment &segment) const {
program.segments.push_back(newSegment);
} break;
default:
throw std::runtime_error("[Declaration::compile] Unimplemented type handler!");
throw std::runtime_error("[Declaration::compile] Invalid type!");
}
}

Expand Down
9 changes: 9 additions & 0 deletions tests/vm_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,15 @@ TEST(VM, SimpleVariableDeclaration) {
ASSERT_EQ(*static_cast<int32_t *>(vm.topStack(sizeof(int32_t))), 42);
}

TEST(VM, VariablesShouldBeInitializedWithZero) {
const char *input = "define a : i32;"
"a;";
VM vm;
auto program = compile(input);
vm.run(program);
ASSERT_EQ(*static_cast<int32_t *>(vm.topStack(sizeof(int32_t))), 0);
}

TEST(VM, TypeDeduction) {
const char *input = "define a = 42;"
"a;";
Expand Down

0 comments on commit 0e17234

Please sign in to comment.