Creating an object of type Boolean should work correctly, as long as the Boolean value being passed is done so as a double*.
This commit is contained in:
+35
-18
@@ -1,6 +1,7 @@
|
|||||||
#include "interpreter.h"
|
#include "interpreter.h"
|
||||||
#include "token.h"
|
#include "token.h"
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
@@ -25,22 +26,22 @@ Object* VisitBinaryExpression(Expr* expression) {
|
|||||||
|
|
||||||
switch(expression->expression.Binary.op->type) {
|
switch(expression->expression.Binary.op->type) {
|
||||||
case Greater:
|
case Greater:
|
||||||
return left > right;
|
//return left > right;
|
||||||
case Greater_Equal:
|
case Greater_Equal:
|
||||||
return left >= right;
|
//return left >= right;
|
||||||
case Less:
|
case Less:
|
||||||
return left < right;
|
//return left < right;
|
||||||
case Less_Equal:
|
case Less_Equal:
|
||||||
return left <= right;
|
//return left <= right;
|
||||||
|
case Bang_Equal:
|
||||||
|
//return !IsEqual(left, right);
|
||||||
|
case Equal_Equal:
|
||||||
|
//return IsEqual(left, right);
|
||||||
case Minus:
|
case Minus:
|
||||||
left->value.number -= right->value.number;
|
left->value.number -= right->value.number;
|
||||||
FreeObject(right);
|
FreeObject(right);
|
||||||
return left;
|
return left;
|
||||||
//return left - right;
|
//return left - right;
|
||||||
case Bang_Equal:
|
|
||||||
return !IsEqual(left, right);
|
|
||||||
case Equal_Equal:
|
|
||||||
return IsEqual(left, right);
|
|
||||||
case Slash:
|
case Slash:
|
||||||
left->value.number /= right->value.number;
|
left->value.number /= right->value.number;
|
||||||
FreeObject(right);
|
FreeObject(right);
|
||||||
@@ -68,6 +69,10 @@ Object* VisitBinaryExpression(Expr* expression) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
FreeObject(left);
|
||||||
|
FreeObject(right);
|
||||||
|
return NULL; //Should be unreachable.
|
||||||
}
|
}
|
||||||
|
|
||||||
FreeObject(left);
|
FreeObject(left);
|
||||||
@@ -77,18 +82,30 @@ Object* VisitBinaryExpression(Expr* expression) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Object* VisitUnaryExpression(Expr* expression) {
|
Object* VisitUnaryExpression(Expr* expression) {
|
||||||
void* right = Evaluate(expression);
|
Object* right = Evaluate(expression);
|
||||||
|
Object* c;
|
||||||
|
double computed_value;
|
||||||
|
|
||||||
switch (expression->type) {
|
switch (expression->expression.Unary.op->type) {
|
||||||
case Minus:
|
case Minus:
|
||||||
|
computed_value = -right->value.number;
|
||||||
|
FreeObject(right);
|
||||||
|
c = CreateObject(&computed_value, Number);
|
||||||
//right needs to be negated, but that kind of introduces a
|
//right needs to be negated, but that kind of introduces a
|
||||||
//memory leak since we can't really change it, what with the
|
//memory leak since we can't really change it, what with the
|
||||||
//whole "const void*" thing and all.
|
//whole "const void*" thing and all.
|
||||||
return right;
|
return c;
|
||||||
case Bang:
|
case Bang:
|
||||||
return !IsTruthy(right);
|
computed_value = !IsTruthy(right);
|
||||||
|
FreeObject(right);
|
||||||
|
c = CreateObject(&computed_value, TRUE); //TRUE or FALSE, doesn't matter here since it becomes INS_BOOLEAN in the end.
|
||||||
|
return c;
|
||||||
|
default:
|
||||||
|
FreeObject(right);
|
||||||
|
return NULL; //Should be unreachable.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FreeObject(right);
|
||||||
return NULL; //Should be unreachable.
|
return NULL; //Should be unreachable.
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -111,22 +128,21 @@ Object* CreateObject(void* value, TokenType type) {
|
|||||||
break;
|
break;
|
||||||
case Number:
|
case Number:
|
||||||
object->instance = INS_DOUBLE;
|
object->instance = INS_DOUBLE;
|
||||||
object->value.number = *((double*) value);
|
object->value.number = *(double*) value;
|
||||||
break;
|
break;
|
||||||
case TRUE:
|
case TRUE:
|
||||||
case FALSE:
|
case FALSE:
|
||||||
object->instance = INS_BOOLEAN;
|
object->instance = INS_BOOLEAN;
|
||||||
object->value.boolean = *((int*) value);
|
object->value.boolean = *(double*) value;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
object->instance = INS_STRING;
|
|
||||||
|
|
||||||
if (value) {
|
if (value) {
|
||||||
int length = strlen(value);
|
int length = strlen(value);
|
||||||
|
object->instance = INS_STRING;
|
||||||
object->value.string = calloc(length + 1, sizeof(char));
|
object->value.string = calloc(length + 1, sizeof(char));
|
||||||
|
|
||||||
strncpy(object->value.string, value, length);
|
strncpy(object->value.string, value, length);
|
||||||
}
|
} else object->instance = INS_NULL; //TODO: this is most likely an error, but we'll ignore that for now.
|
||||||
}
|
}
|
||||||
|
|
||||||
return object;
|
return object;
|
||||||
@@ -154,6 +170,7 @@ int ConcatStringObject(Object* a, const Object* b) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
a->value.string = c;
|
a->value.string = c;
|
||||||
|
a->value.string[a_length + b_length] = '\0';
|
||||||
|
|
||||||
strncat(a->value.string, b->value.string, b_length);
|
strncat(a->value.string, b->value.string, b_length);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user