Add conditionals

This commit is contained in:
Felipe Martinez 2024-07-09 23:02:14 +00:00
parent 23b1bfcb9a
commit c59e29a5c8
2 changed files with 81 additions and 19 deletions

View file

@ -89,7 +89,7 @@ void ASM::run() {
} else {
pc++;
NRF_LOG_INFO("Short opcode: %d", opcode);
switch (opcode) {
case OpcodeShort::WaitRefresh:
return;
@ -153,14 +153,17 @@ void ASM::run() {
break;
case OpcodeShort::Branch: {
uint32_t value = pop_uint32();
if ((value & handler_return_pc_mark) != 0) {
pc = value & ~handler_return_pc_mark;
if (doBranch(pop_uint32()))
return;
}
break;
}
pc = value;
case OpcodeShort::BranchIfTrue: {
uint32_t to = pop_uint32();
auto cond = pop();
if (cond->isTruthy() && doBranch(to))
return;
break;
}
@ -329,9 +332,12 @@ void ASM::run() {
push(std::make_shared<ValueInteger>(pop_uint32() + pop_uint32()));
break;
case OpcodeShort::Subtract:
push(std::make_shared<ValueInteger>(pop_uint32() - pop_uint32()));
case OpcodeShort::Subtract: {
uint32_t b = pop_uint32();
uint32_t a = pop_uint32();
push(std::make_shared<ValueInteger>(a - b));
break;
}
case OpcodeShort::Multiply:
push(std::make_shared<ValueInteger>(pop_uint32() * pop_uint32()));
@ -462,7 +468,21 @@ void ASM::run() {
case OpcodeShort::Equals: {
auto b = pop();
auto a = pop();
push(std::make_shared<ValueInteger>(a.get()->equals(b.get()) ? 1 : 0));
push(std::make_shared<ValueInteger>(a.get()->compare(b.get()) == 0 ? 1 : 0));
break;
}
case OpcodeShort::Greater: {
auto b = pop();
auto a = pop();
push(std::make_shared<ValueInteger>(a.get()->compare(b.get()) > 0 ? 1 : 0));
break;
}
case OpcodeShort::Lesser: {
auto b = pop();
auto a = pop();
push(std::make_shared<ValueInteger>(a.get()->compare(b.get()) < 0 ? 1 : 0));
break;
}
@ -516,6 +536,16 @@ void ASM::_asm_assert(bool condition, const char* msg) {
}
}
bool ASM::doBranch(uint32_t to) {
if ((to & handler_return_pc_mark) != 0) {
pc = to & ~handler_return_pc_mark;
return true;
}
pc = to;
return false;
}
void ASM::OnObjectEvent(lv_obj_t* obj, lv_event_t event) {
if (event != LV_EVENT_CLICKED)
return;

View file

@ -42,7 +42,7 @@ namespace Pinetime {
// TODO: Use fancy C++ type stuff
struct Value {
virtual DataType type() = 0;
virtual bool equals(Value* other) = 0;
virtual int compare(Value* other) = 0;
virtual bool isTruthy() = 0;
};
@ -56,8 +56,20 @@ namespace Pinetime {
return Integer;
}
bool equals(Value* other) override {
return other->type() == Integer && i == static_cast<ValueInteger*>(other)->i;
int compare(Value* other) override {
if (other->type() != Integer) {
return -1;
}
auto otherInt = static_cast<ValueInteger*>(other)->i;
if (i < otherInt) {
return -1;
} else if (i > otherInt) {
return 1;
}
return 0;
}
bool isTruthy() override {
@ -80,8 +92,12 @@ namespace Pinetime {
return String;
}
bool equals(Value* other) override {
return other->type() == String && strcmp(str, static_cast<ValueString*>(other)->str) == 0;
int compare(Value* other) override {
if (other->type() != String) {
return -1;
}
return strcmp(str, static_cast<ValueString*>(other)->str);
}
bool isTruthy() override {
@ -103,8 +119,8 @@ namespace Pinetime {
return LvglObject;
}
bool equals(Value* other) override {
return other->type() == LvglObject && obj == static_cast<ValueLvglObject*>(other)->obj;
int compare(Value*) override {
return -1;
}
bool isTruthy() override {
@ -124,8 +140,20 @@ namespace Pinetime {
return DateTime;
}
bool equals(Value* other) override {
return other->type() == DateTime && time == static_cast<ValueDateTime*>(other)->time;
int compare(Value* other) override {
if (other->type() != DateTime) {
return -1;
}
auto otherTime = static_cast<ValueDateTime*>(other)->time;
if (time < otherTime) {
return -1;
} else if (time > otherTime) {
return 1;
}
return 0;
}
bool isTruthy() override {
@ -137,6 +165,7 @@ namespace Pinetime {
StoreLocal,
LoadLocal,
Branch,
BranchIfTrue,
Call,
Push0,
PushU8,
@ -180,6 +209,8 @@ namespace Pinetime {
Multiply,
Divide,
Equals,
Greater,
Lesser,
Negate,
GrowString,
@ -237,6 +268,7 @@ namespace Pinetime {
void run();
void _asm_assert(bool condition, const char* msg);
bool doBranch(uint32_t to);
std::shared_ptr<Value> pop() {
asm_assert(stack_pointer > 0);