|
@@ -16,12 +16,12 @@ static void sError(Script* sc, const char* format, ...) {
|
|
|
|
|
|
static bool sPrinter(Object* o) {
|
|
static bool sPrinter(Object* o) {
|
|
switch(o->type) {
|
|
switch(o->type) {
|
|
- case OT_INT: printf("%d\n", o->data.intValue); return false;
|
|
|
|
- case OT_FLOAT: printf("%.2f\n", o->data.floatValue); return false;
|
|
|
|
- case OT_CONST_STRING: printf("%s\n", o->data.stringValue); return false;
|
|
|
|
|
|
+ case OT_INT: printf("%d\n", o->as.intValue); return false;
|
|
|
|
+ case OT_FLOAT: printf("%.2f\n", o->as.floatValue); return false;
|
|
|
|
+ case OT_CONST_STRING: printf("%s\n", o->as.stringValue); return false;
|
|
case OT_NULL: printf("null\n"); return false;
|
|
case OT_NULL: printf("null\n"); return false;
|
|
case OT_BOOL:
|
|
case OT_BOOL:
|
|
- printf(o->data.intValue ? "true\n" : "false\n");
|
|
|
|
|
|
+ printf(o->as.intValue ? "true\n" : "false\n");
|
|
return false;
|
|
return false;
|
|
case OT_ARRAY: printf("array\n"); return false;
|
|
case OT_ARRAY: printf("array\n"); return false;
|
|
default: return true;
|
|
default: return true;
|
|
@@ -94,12 +94,12 @@ static Object* sPeek(Script* sc) {
|
|
}
|
|
}
|
|
|
|
|
|
static bool sPushInt(Script* sc, int value) {
|
|
static bool sPushInt(Script* sc, int value) {
|
|
- Object o = {.type = OT_INT, .data.intValue = value};
|
|
|
|
|
|
+ Object o = {.type = OT_INT, .as.intValue = value};
|
|
return sPush(sc, &o);
|
|
return sPush(sc, &o);
|
|
}
|
|
}
|
|
|
|
|
|
static void sPushFloat(Script* sc, float value) {
|
|
static void sPushFloat(Script* sc, float value) {
|
|
- Object o = {.type = OT_FLOAT, .data.floatValue = value};
|
|
|
|
|
|
+ Object o = {.type = OT_FLOAT, .as.floatValue = value};
|
|
sPush(sc, &o);
|
|
sPush(sc, &o);
|
|
}
|
|
}
|
|
|
|
|
|
@@ -109,14 +109,14 @@ static void sPushNull(Script* sc) {
|
|
}
|
|
}
|
|
|
|
|
|
static void sPushBool(Script* sc, bool value) {
|
|
static void sPushBool(Script* sc, bool value) {
|
|
- Object o = {.type = OT_BOOL, .data.intValue = value};
|
|
|
|
|
|
+ Object o = {.type = OT_BOOL, .as.intValue = value};
|
|
sPush(sc, &o);
|
|
sPush(sc, &o);
|
|
}
|
|
}
|
|
|
|
|
|
static void sPushReference(Script* sc, int pointer, int index) {
|
|
static void sPushReference(Script* sc, int pointer, int index) {
|
|
Object o = {.type = OT_REFERENCE,
|
|
Object o = {.type = OT_REFERENCE,
|
|
- .data.reference.pointer = pointer,
|
|
|
|
- .data.reference.index = index};
|
|
|
|
|
|
+ .as.reference.pointer = pointer,
|
|
|
|
+ .as.reference.index = index};
|
|
sPush(sc, &o);
|
|
sPush(sc, &o);
|
|
}
|
|
}
|
|
|
|
|
|
@@ -137,7 +137,7 @@ static void sPopVars(Script* sc) {
|
|
int value = 0;
|
|
int value = 0;
|
|
Object o;
|
|
Object o;
|
|
if(sReadInt(sc, &value) && !sPop(sc, &o) && sCheckType(sc, &o, OT_INT)) {
|
|
if(sReadInt(sc, &value) && !sPop(sc, &o) && sCheckType(sc, &o, OT_INT)) {
|
|
- sc->stackVarIndex = o.data.intValue;
|
|
|
|
|
|
+ sc->stackVarIndex = o.as.intValue;
|
|
if(sc->stackIndex < value) {
|
|
if(sc->stackIndex < value) {
|
|
sError(sc, "stack underflow on line %d", sc->line);
|
|
sError(sc, "stack underflow on line %d", sc->line);
|
|
} else {
|
|
} else {
|
|
@@ -157,13 +157,13 @@ static void sReferenceFromArray(Script* sc) {
|
|
int value = 0;
|
|
int value = 0;
|
|
Object o;
|
|
Object o;
|
|
if(sReadInt(sc, &value) && !sPop(sc, &o) && sCheckType(sc, &o, OT_INT)) {
|
|
if(sReadInt(sc, &value) && !sPop(sc, &o) && sCheckType(sc, &o, OT_INT)) {
|
|
- sPushReference(sc, value, o.data.intValue);
|
|
|
|
|
|
+ sPushReference(sc, value, o.as.intValue);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
static Object* sDereference(Script* sc, Object* reference) {
|
|
static Object* sDereference(Script* sc, Object* reference) {
|
|
- int pointer = reference->data.reference.pointer;
|
|
|
|
- int index = reference->data.reference.index;
|
|
|
|
|
|
+ int pointer = reference->as.reference.pointer;
|
|
|
|
+ int index = reference->as.reference.index;
|
|
if(pointer == -1) {
|
|
if(pointer == -1) {
|
|
if(index < 0 || index >= sc->stackIndex) {
|
|
if(index < 0 || index >= sc->stackIndex) {
|
|
sError(sc, "variable reference index exceeds stack on line %d",
|
|
sError(sc, "variable reference index exceeds stack on line %d",
|
|
@@ -214,13 +214,13 @@ static void sSet(Script* sc) {
|
|
static void sAllocateArray(Script* sc) {
|
|
static void sAllocateArray(Script* sc) {
|
|
Object length;
|
|
Object length;
|
|
if(!sPop(sc, &length) && sCheckType(sc, &length, OT_INT)) {
|
|
if(!sPop(sc, &length) && sCheckType(sc, &length, OT_INT)) {
|
|
- if(length.data.intValue < 0) {
|
|
|
|
|
|
+ if(length.as.intValue < 0) {
|
|
sError(sc, "negative array length on line %d", sc->line);
|
|
sError(sc, "negative array length on line %d", sc->line);
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
Object o = {.type = OT_ARRAY,
|
|
Object o = {.type = OT_ARRAY,
|
|
- .data.intValue =
|
|
|
|
- aAllocate(&sc->allocator, length.data.intValue)};
|
|
|
|
|
|
+ .as.intValue =
|
|
|
|
+ aAllocate(&sc->allocator, length.as.intValue)};
|
|
sPush(sc, &o);
|
|
sPush(sc, &o);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
@@ -228,7 +228,7 @@ static void sAllocateArray(Script* sc) {
|
|
static void sArrayLength(Script* sc) {
|
|
static void sArrayLength(Script* sc) {
|
|
Object* o = sPopAndDereference(sc);
|
|
Object* o = sPopAndDereference(sc);
|
|
if(o != NULL && sCheckType(sc, o, OT_ARRAY)) {
|
|
if(o != NULL && sCheckType(sc, o, OT_ARRAY)) {
|
|
- int arrayPointer = o->data.intValue;
|
|
|
|
|
|
+ int arrayPointer = o->as.intValue;
|
|
if(arrayPointer < 0 || arrayPointer >= sc->allocator.capacity) {
|
|
if(arrayPointer < 0 || arrayPointer >= sc->allocator.capacity) {
|
|
sError(sc, "array pointer is out of range on line %d\n", sc->line);
|
|
sError(sc, "array pointer is out of range on line %d\n", sc->line);
|
|
return;
|
|
return;
|
|
@@ -241,9 +241,9 @@ static void sPreChange(Script* sc, int change) {
|
|
Object* o = sPopAndDereference(sc);
|
|
Object* o = sPopAndDereference(sc);
|
|
if(o != NULL) {
|
|
if(o != NULL) {
|
|
if(o->type == OT_INT) {
|
|
if(o->type == OT_INT) {
|
|
- o->data.intValue += change;
|
|
|
|
|
|
+ o->as.intValue += change;
|
|
} else if(o->type == OT_FLOAT) {
|
|
} else if(o->type == OT_FLOAT) {
|
|
- o->data.floatValue += change;
|
|
|
|
|
|
+ o->as.floatValue += change;
|
|
} else {
|
|
} else {
|
|
sError(sc, "variable is '%s' not a number on line %d",
|
|
sError(sc, "variable is '%s' not a number on line %d",
|
|
oGetName(o->type), sc->line);
|
|
oGetName(o->type), sc->line);
|
|
@@ -266,10 +266,10 @@ static void sPostChange(Script* sc, int change) {
|
|
if(o != NULL) {
|
|
if(o != NULL) {
|
|
if(o->type == OT_INT) {
|
|
if(o->type == OT_INT) {
|
|
sPush(sc, o);
|
|
sPush(sc, o);
|
|
- o->data.intValue += change;
|
|
|
|
|
|
+ o->as.intValue += change;
|
|
} else if(o->type == OT_FLOAT) {
|
|
} else if(o->type == OT_FLOAT) {
|
|
sPush(sc, o);
|
|
sPush(sc, o);
|
|
- o->data.floatValue += change;
|
|
|
|
|
|
+ o->as.floatValue += change;
|
|
} else {
|
|
} else {
|
|
sError(sc, "variable is '%s' not a number on line %d",
|
|
sError(sc, "variable is '%s' not a number on line %d",
|
|
oGetName(o->type), sc->line);
|
|
oGetName(o->type), sc->line);
|
|
@@ -307,7 +307,7 @@ static void sPushCodeString(Script* sc) {
|
|
if(sReadInt(sc, &value)) {
|
|
if(sReadInt(sc, &value)) {
|
|
char* s = (char*)(sc->code->code + sc->readIndex);
|
|
char* s = (char*)(sc->code->code + sc->readIndex);
|
|
sc->readIndex += value;
|
|
sc->readIndex += value;
|
|
- Object o = {.type = OT_CONST_STRING, .data.stringValue = s};
|
|
|
|
|
|
+ Object o = {.type = OT_CONST_STRING, .as.stringValue = s};
|
|
sPush(sc, &o);
|
|
sPush(sc, &o);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
@@ -318,13 +318,13 @@ static void sPushCodeString(Script* sc) {
|
|
if(sPop(sc, o) || sPop(sc, o + 1)) { \
|
|
if(sPop(sc, o) || sPop(sc, o + 1)) { \
|
|
return; \
|
|
return; \
|
|
} else if(o[0].type == OT_INT && o[1].type == OT_INT) { \
|
|
} else if(o[0].type == OT_INT && o[1].type == OT_INT) { \
|
|
- check sPush##typeA(sc, o[1].data.intValue op o[0].data.intValue); \
|
|
|
|
|
|
+ check sPush##typeA(sc, o[1].as.intValue op o[0].as.intValue); \
|
|
} else if(o[0].type == OT_INT && o[1].type == OT_FLOAT) { \
|
|
} else if(o[0].type == OT_INT && o[1].type == OT_FLOAT) { \
|
|
- sPush##typeB(sc, o[1].data.floatValue op o[0].data.intValue); \
|
|
|
|
|
|
+ sPush##typeB(sc, o[1].as.floatValue op o[0].as.intValue); \
|
|
} else if(o[0].type == OT_FLOAT && o[1].type == OT_INT) { \
|
|
} else if(o[0].type == OT_FLOAT && o[1].type == OT_INT) { \
|
|
- sPush##typeB(sc, o[1].data.intValue op o[0].data.floatValue); \
|
|
|
|
|
|
+ sPush##typeB(sc, o[1].as.intValue op o[0].as.floatValue); \
|
|
} else if(o[0].type == OT_FLOAT && o[1].type == OT_FLOAT) { \
|
|
} else if(o[0].type == OT_FLOAT && o[1].type == OT_FLOAT) { \
|
|
- sPush##typeB(sc, o[1].data.floatValue op o[0].data.floatValue); \
|
|
|
|
|
|
+ sPush##typeB(sc, o[1].as.floatValue op o[0].as.floatValue); \
|
|
} else { \
|
|
} else { \
|
|
sError(sc, "object is not a number on line %d", sc->line); \
|
|
sError(sc, "object is not a number on line %d", sc->line); \
|
|
} \
|
|
} \
|
|
@@ -336,12 +336,12 @@ static void sPushCodeString(Script* sc) {
|
|
Object o[2]; \
|
|
Object o[2]; \
|
|
if(!sPop(sc, o) && !sPop(sc, o + 1) && sCheckType(sc, o, OT_INT) && \
|
|
if(!sPop(sc, o) && !sPop(sc, o + 1) && sCheckType(sc, o, OT_INT) && \
|
|
sCheckType(sc, o + 1, OT_INT)) { \
|
|
sCheckType(sc, o + 1, OT_INT)) { \
|
|
- check sPushInt(sc, o[1].data.intValue op o[0].data.intValue); \
|
|
|
|
|
|
+ check sPushInt(sc, o[1].as.intValue op o[0].as.intValue); \
|
|
} \
|
|
} \
|
|
}
|
|
}
|
|
#define INT_OP(op) CHECKED_INT_OP(, op)
|
|
#define INT_OP(op) CHECKED_INT_OP(, op)
|
|
#define ZERO_CHECK(op) \
|
|
#define ZERO_CHECK(op) \
|
|
- if(o[0].data.intValue == 0) { \
|
|
|
|
|
|
+ if(o[0].as.intValue == 0) { \
|
|
sError(sc, op " by 0 on line %d", sc->line); \
|
|
sError(sc, op " by 0 on line %d", sc->line); \
|
|
return; \
|
|
return; \
|
|
}
|
|
}
|
|
@@ -353,9 +353,9 @@ static void sInvertSign(Script* sc) {
|
|
if(o == NULL) {
|
|
if(o == NULL) {
|
|
return;
|
|
return;
|
|
} else if(o->type == OT_INT) {
|
|
} else if(o->type == OT_INT) {
|
|
- o->data.intValue = -o->data.intValue;
|
|
|
|
|
|
+ o->as.intValue = -o->as.intValue;
|
|
} else if(o->type == OT_FLOAT) {
|
|
} else if(o->type == OT_FLOAT) {
|
|
- o->data.floatValue = -o->data.floatValue;
|
|
|
|
|
|
+ o->as.floatValue = -o->as.floatValue;
|
|
} else {
|
|
} else {
|
|
sError(sc, "object is not a number on line %d", sc->line);
|
|
sError(sc, "object is not a number on line %d", sc->line);
|
|
}
|
|
}
|
|
@@ -366,15 +366,15 @@ static void sEqual(Script* sc) {
|
|
if(sPop(sc, o) || sPop(sc, o + 1)) {
|
|
if(sPop(sc, o) || sPop(sc, o + 1)) {
|
|
return;
|
|
return;
|
|
} else if(o[0].type == OT_INT && o[1].type == OT_INT) {
|
|
} else if(o[0].type == OT_INT && o[1].type == OT_INT) {
|
|
- sPushBool(sc, o[0].data.intValue == o[1].data.intValue);
|
|
|
|
|
|
+ sPushBool(sc, o[0].as.intValue == o[1].as.intValue);
|
|
} else if(o[0].type == OT_INT && o[1].type == OT_FLOAT) {
|
|
} else if(o[0].type == OT_INT && o[1].type == OT_FLOAT) {
|
|
- sPushBool(sc, o[0].data.intValue == o[1].data.floatValue);
|
|
|
|
|
|
+ sPushBool(sc, o[0].as.intValue == o[1].as.floatValue);
|
|
} else if(o[0].type == OT_FLOAT && o[1].type == OT_INT) {
|
|
} else if(o[0].type == OT_FLOAT && o[1].type == OT_INT) {
|
|
- sPushBool(sc, o[0].data.floatValue == o[1].data.intValue);
|
|
|
|
|
|
+ sPushBool(sc, o[0].as.floatValue == o[1].as.intValue);
|
|
} else if(o[0].type == OT_FLOAT && o[1].type == OT_FLOAT) {
|
|
} else if(o[0].type == OT_FLOAT && o[1].type == OT_FLOAT) {
|
|
- sPushBool(sc, o[0].data.floatValue == o[1].data.floatValue);
|
|
|
|
|
|
+ sPushBool(sc, o[0].as.floatValue == o[1].as.floatValue);
|
|
} else if(o[0].type == OT_BOOL && o[1].type == OT_BOOL) {
|
|
} else if(o[0].type == OT_BOOL && o[1].type == OT_BOOL) {
|
|
- sPushBool(sc, o[0].data.intValue == o[1].data.intValue);
|
|
|
|
|
|
+ sPushBool(sc, o[0].as.intValue == o[1].as.intValue);
|
|
} else if(o[0].type == OT_NULL && o[1].type == OT_NULL) {
|
|
} else if(o[0].type == OT_NULL && o[1].type == OT_NULL) {
|
|
sPushBool(sc, true);
|
|
sPushBool(sc, true);
|
|
} else {
|
|
} else {
|
|
@@ -385,14 +385,14 @@ static void sEqual(Script* sc) {
|
|
static void sNot(Script* sc) {
|
|
static void sNot(Script* sc) {
|
|
Object* o = sPeek(sc);
|
|
Object* o = sPeek(sc);
|
|
if(o != NULL && sCheckType(sc, o, OT_BOOL)) {
|
|
if(o != NULL && sCheckType(sc, o, OT_BOOL)) {
|
|
- o->data.intValue = !o->data.intValue;
|
|
|
|
|
|
+ o->as.intValue = !o->as.intValue;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
static void sBitNot(Script* sc) {
|
|
static void sBitNot(Script* sc) {
|
|
Object* o = sPeek(sc);
|
|
Object* o = sPeek(sc);
|
|
if(o != NULL && sCheckType(sc, o, OT_INT)) {
|
|
if(o != NULL && sCheckType(sc, o, OT_INT)) {
|
|
- o->data.intValue = ~o->data.intValue;
|
|
|
|
|
|
+ o->as.intValue = ~o->as.intValue;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
@@ -400,7 +400,7 @@ static void sAnd(Script* sc) {
|
|
Object o[2];
|
|
Object o[2];
|
|
if(!sPop(sc, o) && !sPop(sc, o + 1) && sCheckType(sc, o, OT_BOOL) &&
|
|
if(!sPop(sc, o) && !sPop(sc, o + 1) && sCheckType(sc, o, OT_BOOL) &&
|
|
sCheckType(sc, o + 1, OT_BOOL)) {
|
|
sCheckType(sc, o + 1, OT_BOOL)) {
|
|
- sPushBool(sc, o[0].data.intValue && o[1].data.intValue);
|
|
|
|
|
|
+ sPushBool(sc, o[0].as.intValue && o[1].as.intValue);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
@@ -408,7 +408,7 @@ static void sOr(Script* sc) {
|
|
Object o[2];
|
|
Object o[2];
|
|
if(!sPop(sc, o) && !sPop(sc, o + 1) && sCheckType(sc, o, OT_BOOL) &&
|
|
if(!sPop(sc, o) && !sPop(sc, o + 1) && sCheckType(sc, o, OT_BOOL) &&
|
|
sCheckType(sc, o + 1, OT_BOOL)) {
|
|
sCheckType(sc, o + 1, OT_BOOL)) {
|
|
- sPushBool(sc, o[0].data.intValue || o[1].data.intValue);
|
|
|
|
|
|
+ sPushBool(sc, o[0].as.intValue || o[1].as.intValue);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
@@ -442,7 +442,7 @@ static void sGoSub(Script* sc) {
|
|
sc->line);
|
|
sc->line);
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
- sc->stack[returnStackIndex].data.intValue = sc->readIndex;
|
|
|
|
|
|
+ sc->stack[returnStackIndex].as.intValue = sc->readIndex;
|
|
sc->readIndex = gotoIndex;
|
|
sc->readIndex = gotoIndex;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
@@ -451,7 +451,7 @@ static void sIfGoTo(Script* sc) {
|
|
int gotoIndex;
|
|
int gotoIndex;
|
|
Object o;
|
|
Object o;
|
|
if(sReadInt(sc, &gotoIndex) && !sPop(sc, &o) &&
|
|
if(sReadInt(sc, &gotoIndex) && !sPop(sc, &o) &&
|
|
- sCheckType(sc, &o, OT_BOOL) && !o.data.intValue) {
|
|
|
|
|
|
+ sCheckType(sc, &o, OT_BOOL) && !o.as.intValue) {
|
|
sc->readIndex = gotoIndex;
|
|
sc->readIndex = gotoIndex;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
@@ -463,7 +463,7 @@ static void sSetReturn(Script* sc) {
|
|
static void sReturn(Script* sc) {
|
|
static void sReturn(Script* sc) {
|
|
Object o;
|
|
Object o;
|
|
if(!sPop(sc, &o) && sCheckType(sc, &o, OT_INT)) {
|
|
if(!sPop(sc, &o) && sCheckType(sc, &o, OT_INT)) {
|
|
- sc->readIndex = o.data.intValue;
|
|
|
|
|
|
+ sc->readIndex = o.as.intValue;
|
|
if(sc->returnValue.type != OT_VOID) {
|
|
if(sc->returnValue.type != OT_VOID) {
|
|
sPush(sc, &sc->returnValue);
|
|
sPush(sc, &sc->returnValue);
|
|
sc->returnValue.type = OT_VOID;
|
|
sc->returnValue.type = OT_VOID;
|
|
@@ -569,7 +569,7 @@ void sSetPrinter(ObjectPrinter p) {
|
|
|
|
|
|
static void sMark(Script* sc, Object* o) {
|
|
static void sMark(Script* sc, Object* o) {
|
|
if(o->type == OT_ARRAY) {
|
|
if(o->type == OT_ARRAY) {
|
|
- Array* a = sc->allocator.data + o->data.intValue;
|
|
|
|
|
|
+ Array* a = sc->allocator.data + o->as.intValue;
|
|
a->marked = true;
|
|
a->marked = true;
|
|
for(int i = 0; i < a->length; i++) {
|
|
for(int i = 0; i < a->length; i++) {
|
|
sMark(sc, a->data + i);
|
|
sMark(sc, a->data + i);
|