|
@@ -32,9 +32,7 @@ static ObjectPrinter printer = sPrinter;
|
|
|
|
|
|
static bool sRead(Script* sc, void* buffer, int length) {
|
|
|
if(sc->readIndex + length > sc->code->length) {
|
|
|
- sError(sc,
|
|
|
- "cannot read expected %d bytes of data from bytecode on line %d",
|
|
|
- sc->line);
|
|
|
+ sError(sc, "cannot read expected %d bytes of data from bytecode");
|
|
|
return true;
|
|
|
}
|
|
|
memcpy(buffer, sc->code->code + sc->readIndex, length);
|
|
@@ -58,13 +56,13 @@ static bool sCheckType(Script* sc, Object* o, ObjectType ot) {
|
|
|
if(o->type == ot) {
|
|
|
return true;
|
|
|
}
|
|
|
- sError(sc, "object is not of type %s on line %d", oGetName(ot), sc->line);
|
|
|
+ sError(sc, "object is not of type %s", oGetName(ot));
|
|
|
return false;
|
|
|
}
|
|
|
|
|
|
static bool sPush(Script* sc, Object* o) {
|
|
|
if(sc->stackIndex >= SCRIPT_STACK_SIZE) {
|
|
|
- sError(sc, "stack overflow on line %d", sc->line);
|
|
|
+ sError(sc, "stack overflow");
|
|
|
return false;
|
|
|
}
|
|
|
sc->stack[sc->stackIndex++] = *o;
|
|
@@ -73,7 +71,7 @@ static bool sPush(Script* sc, Object* o) {
|
|
|
|
|
|
static bool sPop(Script* sc, Object* o) {
|
|
|
if(sc->stackIndex <= 0) {
|
|
|
- sError(sc, "stack underflow on line %d", sc->line);
|
|
|
+ sError(sc, "stack underflow");
|
|
|
return true;
|
|
|
}
|
|
|
*o = sc->stack[--sc->stackIndex];
|
|
@@ -87,7 +85,7 @@ static void sPopEmpty(Script* sc) {
|
|
|
|
|
|
static Object* sPeek(Script* sc) {
|
|
|
if(sc->stackIndex <= 0) {
|
|
|
- sError(sc, "stack underflow on line %d", sc->line);
|
|
|
+ sError(sc, "stack underflow");
|
|
|
return NULL;
|
|
|
}
|
|
|
return sc->stack + (sc->stackIndex - 1);
|
|
@@ -139,7 +137,7 @@ static void sPopVars(Script* sc) {
|
|
|
if(sReadInt(sc, &value) && !sPop(sc, &o) && sCheckType(sc, &o, OT_INT)) {
|
|
|
sc->stackVarIndex = o.as.intValue;
|
|
|
if(sc->stackIndex < value) {
|
|
|
- sError(sc, "stack underflow on line %d", sc->line);
|
|
|
+ sError(sc, "stack underflow");
|
|
|
} else {
|
|
|
sc->stackIndex -= value;
|
|
|
}
|
|
@@ -166,19 +164,16 @@ static Object* sDereference(Script* sc, Object* reference) {
|
|
|
int index = reference->as.reference.index;
|
|
|
if(pointer == -1) {
|
|
|
if(index < 0 || index >= sc->stackIndex) {
|
|
|
- sError(sc, "variable reference index exceeds stack on line %d",
|
|
|
- sc->line);
|
|
|
+ sError(sc, "variable reference index exceeds stack");
|
|
|
return NULL;
|
|
|
}
|
|
|
return sc->stack + index;
|
|
|
} else {
|
|
|
if(pointer < 0 || pointer >= sc->allocator.capacity) {
|
|
|
- sError(sc, "array reference pointer is out of range on line %d\n",
|
|
|
- sc->line);
|
|
|
+ sError(sc, "array reference pointer is out of range");
|
|
|
return NULL;
|
|
|
} else if(index < 0 || index >= sc->allocator.data[pointer].length) {
|
|
|
- sError(sc, "array reference index is out of bounds on line %d\n",
|
|
|
- sc->line);
|
|
|
+ sError(sc, "array reference index is out of bounds");
|
|
|
return NULL;
|
|
|
}
|
|
|
return sc->allocator.data[pointer].data + index;
|
|
@@ -215,7 +210,7 @@ static void sAllocateArray(Script* sc) {
|
|
|
Object length;
|
|
|
if(!sPop(sc, &length) && sCheckType(sc, &length, OT_INT)) {
|
|
|
if(length.as.intValue < 0) {
|
|
|
- sError(sc, "negative array length on line %d", sc->line);
|
|
|
+ sError(sc, "negative array length");
|
|
|
return;
|
|
|
}
|
|
|
Object o = {.type = OT_ARRAY,
|
|
@@ -230,7 +225,7 @@ static void sArrayLength(Script* sc) {
|
|
|
if(o != NULL && sCheckType(sc, o, OT_ARRAY)) {
|
|
|
int arrayPointer = o->as.intValue;
|
|
|
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");
|
|
|
return;
|
|
|
}
|
|
|
sPushInt(sc, sc->allocator.data[arrayPointer].length);
|
|
@@ -245,8 +240,7 @@ static void sPreChange(Script* sc, int change) {
|
|
|
} else if(o->type == OT_FLOAT) {
|
|
|
o->as.floatValue += change;
|
|
|
} else {
|
|
|
- sError(sc, "variable is '%s' not a number on line %d",
|
|
|
- oGetName(o->type), sc->line);
|
|
|
+ sError(sc, "variable is '%s' not a number", oGetName(o->type));
|
|
|
return;
|
|
|
}
|
|
|
sPush(sc, o);
|
|
@@ -271,8 +265,7 @@ static void sPostChange(Script* sc, int change) {
|
|
|
sPush(sc, o);
|
|
|
o->as.floatValue += change;
|
|
|
} else {
|
|
|
- sError(sc, "variable is '%s' not a number on line %d",
|
|
|
- oGetName(o->type), sc->line);
|
|
|
+ sError(sc, "variable is '%s' not a number", oGetName(o->type));
|
|
|
}
|
|
|
}
|
|
|
}
|
|
@@ -295,8 +288,7 @@ static void sPushCodeInt(Script* sc) {
|
|
|
static void sPushCodeFloat(Script* sc) {
|
|
|
float value = 0;
|
|
|
if(sRead(sc, &value, sizeof(float))) {
|
|
|
- sError(sc, "cannot read a float from the bytecode on line %d",
|
|
|
- sc->line);
|
|
|
+ sError(sc, "cannot read a float from the bytecode");
|
|
|
return;
|
|
|
}
|
|
|
sPushFloat(sc, value);
|
|
@@ -326,7 +318,7 @@ static void sPushCodeString(Script* sc) {
|
|
|
} else if(o[0].type == OT_FLOAT && o[1].type == OT_FLOAT) { \
|
|
|
sPush##typeB(sc, o[1].as.floatValue op o[0].as.floatValue); \
|
|
|
} else { \
|
|
|
- sError(sc, "object is not a number on line %d", sc->line); \
|
|
|
+ sError(sc, "object is not a number"); \
|
|
|
} \
|
|
|
}
|
|
|
#define NUMBER_NUMBER_OP(op) CHECKED_NUMBER_OP(, op, Int, Float)
|
|
@@ -342,7 +334,7 @@ static void sPushCodeString(Script* sc) {
|
|
|
#define INT_OP(op) CHECKED_INT_OP(, op)
|
|
|
#define ZERO_CHECK(op) \
|
|
|
if(o[0].as.intValue == 0) { \
|
|
|
- sError(sc, op " by 0 on line %d", sc->line); \
|
|
|
+ sError(sc, op " by 0"); \
|
|
|
return; \
|
|
|
}
|
|
|
#define DIVISION CHECKED_NUMBER_OP(ZERO_CHECK("division"), /, Int, Float)
|
|
@@ -357,7 +349,7 @@ static void sInvertSign(Script* sc) {
|
|
|
} else if(o->type == OT_FLOAT) {
|
|
|
o->as.floatValue = -o->as.floatValue;
|
|
|
} else {
|
|
|
- sError(sc, "object is not a number on line %d", sc->line);
|
|
|
+ sError(sc, "object is not a number");
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -378,7 +370,7 @@ static void sEqual(Script* sc) {
|
|
|
} else if(o[0].type == OT_NULL && o[1].type == OT_NULL) {
|
|
|
sPushBool(sc, true);
|
|
|
} else {
|
|
|
- sError(sc, "object types do not match on line %d", sc->line);
|
|
|
+ sError(sc, "object types do not match");
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -415,13 +407,13 @@ static void sOr(Script* sc) {
|
|
|
static void sPrint(Script* sc) {
|
|
|
Object o;
|
|
|
if(!sPop(sc, &o) && printer(&o)) {
|
|
|
- sError(sc, "cannot print given object on line %d", sc->line);
|
|
|
+ sError(sc, "cannot print given object");
|
|
|
}
|
|
|
}
|
|
|
|
|
|
static void sLine(Script* sc) {
|
|
|
if(sRead(sc, &sc->line, 2)) {
|
|
|
- sError(sc, "line operation without a line near line %d", sc->line);
|
|
|
+ sError(sc, "line operation without a line");
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -438,8 +430,7 @@ static void sGoSub(Script* sc) {
|
|
|
if(sReadInt(sc, &gotoIndex) && sReadInt(sc, &arguments)) {
|
|
|
int returnStackIndex = sc->stackIndex - arguments - 1;
|
|
|
if(returnStackIndex < 0 || sc->stack[returnStackIndex].type != OT_INT) {
|
|
|
- sError(sc, "cannot find return address entry on stack on line %d",
|
|
|
- sc->line);
|
|
|
+ sError(sc, "cannot find return address on stack");
|
|
|
return;
|
|
|
}
|
|
|
sc->stack[returnStackIndex].as.intValue = sc->readIndex;
|
|
@@ -557,7 +548,9 @@ void sRun(Script* sc) {
|
|
|
while(sHasData(sc)) {
|
|
|
sConsumeInstruction(sc);
|
|
|
if(sc->error[0] != '\0') {
|
|
|
- puts(sc->error);
|
|
|
+ puts("error:");
|
|
|
+ printf(" - info: %s\n", sc->error);
|
|
|
+ printf(" - line: %d\n", sc->line);
|
|
|
return;
|
|
|
}
|
|
|
}
|