Start working on allowing more types in compiler
This commit is contained in:
240
src/compiler.c
240
src/compiler.c
@@ -13,7 +13,7 @@ VariableTable createVariableTable() {
|
|||||||
return vt;
|
return vt;
|
||||||
}
|
}
|
||||||
|
|
||||||
void addVtVariable(VariableTable* vt, const char* name) {
|
void addVtVariable(VariableTable* vt, const char* name, GroundValueType type) {
|
||||||
// check if it already exists
|
// check if it already exists
|
||||||
for (size_t i = 0; i < vt->count; i++) {
|
for (size_t i = 0; i < vt->count; i++) {
|
||||||
if (strcmp(vt->vars[i].name, name) == 0) {
|
if (strcmp(vt->vars[i].name, name) == 0) {
|
||||||
@@ -29,10 +29,20 @@ void addVtVariable(VariableTable* vt, const char* name) {
|
|||||||
|
|
||||||
// add the variable
|
// add the variable
|
||||||
strcpy(vt->vars[vt->count].name, name);
|
strcpy(vt->vars[vt->count].name, name);
|
||||||
|
vt->vars[vt->count].type = type;
|
||||||
vt->vars[vt->count].offset = vt->count * 8;
|
vt->vars[vt->count].offset = vt->count * 8;
|
||||||
vt->count++;
|
vt->count++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
VariableInfo* getVariable(VariableTable* vt, const char* name) {
|
||||||
|
for (size_t i = 0; i < vt->count; i++) {
|
||||||
|
if (strcmp(vt->vars[i].name, name) == 0) {
|
||||||
|
return &vt->vars[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
int getVariablePos(VariableTable* vt, const char* name) {
|
int getVariablePos(VariableTable* vt, const char* name) {
|
||||||
for (size_t i = 0; i < vt->count; i++) {
|
for (size_t i = 0; i < vt->count; i++) {
|
||||||
if (strcmp(vt->vars[i].name, name) == 0) {
|
if (strcmp(vt->vars[i].name, name) == 0) {
|
||||||
@@ -42,6 +52,232 @@ int getVariablePos(VariableTable* vt, const char* name) {
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GroundValueType getInstructionReturnType(GroundInstruction* gi, VariableTable* table) {
|
||||||
|
switch (gi->type) {
|
||||||
|
case JUMP:
|
||||||
|
case PRINT:
|
||||||
|
case PRINTLN:
|
||||||
|
case END:
|
||||||
|
case IF:
|
||||||
|
case RETURN:
|
||||||
|
case ENDFUN:
|
||||||
|
case PUSHARG:
|
||||||
|
case CALL: // FIXME do this when functions are added
|
||||||
|
case USE:
|
||||||
|
case EXTERN:
|
||||||
|
case CREATELABEL:
|
||||||
|
case PAUSE:
|
||||||
|
case DROP:
|
||||||
|
case ERRORCMD:
|
||||||
|
case ENDSTRUCT:
|
||||||
|
case INIT: // FIXME do this when objects are added
|
||||||
|
case GETFIELD: // FIXME do this when objects are added
|
||||||
|
case SETFIELD: // FIXME do this when objects are added
|
||||||
|
case DIVIDE: // FIXME do this when division is added
|
||||||
|
case SETLISTAT:
|
||||||
|
case GETLISTAT: // FIXME do this when lists are getting implemented
|
||||||
|
case LISTAPPEND: {
|
||||||
|
return NONE;
|
||||||
|
}
|
||||||
|
case TOSTRING:
|
||||||
|
case GETTYPE:
|
||||||
|
case INPUT: {
|
||||||
|
return STRING;
|
||||||
|
}
|
||||||
|
case STOI:
|
||||||
|
case GETLISTSIZE:
|
||||||
|
case GETSTRSIZE: {
|
||||||
|
return INT;
|
||||||
|
}
|
||||||
|
case STOD: {
|
||||||
|
return DOUBLE;
|
||||||
|
}
|
||||||
|
case EQUAL:
|
||||||
|
case INEQUAL:
|
||||||
|
case GREATER:
|
||||||
|
case LESSER:
|
||||||
|
case NOT:
|
||||||
|
case EXISTS: {
|
||||||
|
return BOOL;
|
||||||
|
}
|
||||||
|
case GETSTRCHARAT: {
|
||||||
|
return CHAR;
|
||||||
|
}
|
||||||
|
case SETLIST: {
|
||||||
|
return LIST;
|
||||||
|
}
|
||||||
|
case FUN: {
|
||||||
|
return FUNCTION;
|
||||||
|
}
|
||||||
|
case STRUCT: {
|
||||||
|
return STRUCTVAL;
|
||||||
|
}
|
||||||
|
case SET: {
|
||||||
|
if (gi->args.length == 2) {
|
||||||
|
if (gi->args.args[0].type == VALUE) {
|
||||||
|
return gi->args.args[0].value.value.type;
|
||||||
|
} else if (gi->args.args[0].type == VALREF) {
|
||||||
|
VariableInfo* var = getVariable(table, gi->args.args[0].value.refName);
|
||||||
|
if (var == NULL) {
|
||||||
|
return NONE;
|
||||||
|
}
|
||||||
|
return var->type;
|
||||||
|
} else {
|
||||||
|
return NONE;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return NONE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case ADD: {
|
||||||
|
if (gi->args.length == 3) {
|
||||||
|
GroundValueType leftType;
|
||||||
|
GroundValueType rightType;
|
||||||
|
if (gi->args.args[0].type == VALUE) {
|
||||||
|
leftType = gi->args.args[0].value.value.type;
|
||||||
|
} else if (gi->args.args[0].type == VALREF) {
|
||||||
|
VariableInfo* var = getVariable(table, gi->args.args[0].value.refName);
|
||||||
|
if (var == NULL) {
|
||||||
|
return NONE;
|
||||||
|
}
|
||||||
|
leftType = var->type;
|
||||||
|
} else {
|
||||||
|
return NONE;
|
||||||
|
}
|
||||||
|
if (gi->args.args[1].type == VALUE) {
|
||||||
|
rightType = gi->args.args[1].value.value.type;
|
||||||
|
} else if (gi->args.args[1].type == VALREF) {
|
||||||
|
VariableInfo* var = getVariable(table, gi->args.args[1].value.refName);
|
||||||
|
if (var == NULL) {
|
||||||
|
return NONE;
|
||||||
|
}
|
||||||
|
rightType = var->type;
|
||||||
|
} else {
|
||||||
|
return NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (leftType == STRING) {
|
||||||
|
if (rightType == STRING) {
|
||||||
|
return STRING;
|
||||||
|
} else {
|
||||||
|
return NONE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (leftType == DOUBLE) {
|
||||||
|
if (rightType == DOUBLE || rightType == INT) {
|
||||||
|
return DOUBLE;
|
||||||
|
} else {
|
||||||
|
return NONE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (rightType == DOUBLE) {
|
||||||
|
if (leftType == DOUBLE || leftType == INT) {
|
||||||
|
return DOUBLE;
|
||||||
|
} else {
|
||||||
|
return NONE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NONE;
|
||||||
|
} else {
|
||||||
|
return NONE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case SUBTRACT: {
|
||||||
|
if (gi->args.length == 3) {
|
||||||
|
GroundValueType leftType;
|
||||||
|
GroundValueType rightType;
|
||||||
|
if (gi->args.args[0].type == VALUE) {
|
||||||
|
leftType = gi->args.args[0].value.value.type;
|
||||||
|
} else if (gi->args.args[0].type == VALREF) {
|
||||||
|
VariableInfo* var = getVariable(table, gi->args.args[0].value.refName);
|
||||||
|
if (var == NULL) {
|
||||||
|
return NONE;
|
||||||
|
}
|
||||||
|
leftType = var->type;
|
||||||
|
} else {
|
||||||
|
return NONE;
|
||||||
|
}
|
||||||
|
if (gi->args.args[1].type == VALUE) {
|
||||||
|
rightType = gi->args.args[1].value.value.type;
|
||||||
|
} else if (gi->args.args[1].type == VALREF) {
|
||||||
|
VariableInfo* var = getVariable(table, gi->args.args[1].value.refName);
|
||||||
|
if (var == NULL) {
|
||||||
|
return NONE;
|
||||||
|
}
|
||||||
|
rightType = var->type;
|
||||||
|
} else {
|
||||||
|
return NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (leftType == DOUBLE) {
|
||||||
|
if (rightType == DOUBLE || rightType == INT) {
|
||||||
|
return DOUBLE;
|
||||||
|
} else {
|
||||||
|
return NONE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (rightType == DOUBLE) {
|
||||||
|
if (leftType == DOUBLE || leftType == INT) {
|
||||||
|
return DOUBLE;
|
||||||
|
} else {
|
||||||
|
return NONE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NONE;
|
||||||
|
} else {
|
||||||
|
return NONE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case MULTIPLY: {
|
||||||
|
if (gi->args.length == 3) {
|
||||||
|
GroundValueType leftType;
|
||||||
|
GroundValueType rightType;
|
||||||
|
if (gi->args.args[0].type == VALUE) {
|
||||||
|
leftType = gi->args.args[0].value.value.type;
|
||||||
|
} else if (gi->args.args[0].type == VALREF) {
|
||||||
|
VariableInfo* var = getVariable(table, gi->args.args[0].value.refName);
|
||||||
|
if (var == NULL) {
|
||||||
|
return NONE;
|
||||||
|
}
|
||||||
|
leftType = var->type;
|
||||||
|
} else {
|
||||||
|
return NONE;
|
||||||
|
}
|
||||||
|
if (gi->args.args[1].type == VALUE) {
|
||||||
|
rightType = gi->args.args[1].value.value.type;
|
||||||
|
} else if (gi->args.args[1].type == VALREF) {
|
||||||
|
VariableInfo* var = getVariable(table, gi->args.args[1].value.refName);
|
||||||
|
if (var == NULL) {
|
||||||
|
return NONE;
|
||||||
|
}
|
||||||
|
rightType = var->type;
|
||||||
|
} else {
|
||||||
|
return NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (leftType == DOUBLE) {
|
||||||
|
if (rightType == DOUBLE || rightType == INT) {
|
||||||
|
return DOUBLE;
|
||||||
|
} else {
|
||||||
|
return NONE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (rightType == DOUBLE) {
|
||||||
|
if (leftType == DOUBLE || leftType == INT) {
|
||||||
|
return DOUBLE;
|
||||||
|
} else {
|
||||||
|
return NONE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NONE;
|
||||||
|
} else {
|
||||||
|
return NONE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return INT;
|
||||||
|
}
|
||||||
|
|
||||||
char* processValueString(GroundArg arg) {
|
char* processValueString(GroundArg arg) {
|
||||||
if (arg.type == VALREF) {
|
if (arg.type == VALREF) {
|
||||||
char* buf = malloc(sizeof(char) * 260);
|
char* buf = malloc(sizeof(char) * 260);
|
||||||
@@ -124,7 +360,7 @@ char* compileGroundProgram(GroundProgram* program) {
|
|||||||
GroundInstruction gi = program->instructions[i];
|
GroundInstruction gi = program->instructions[i];
|
||||||
for (size_t j = 0; j < gi.args.length; j++) {
|
for (size_t j = 0; j < gi.args.length; j++) {
|
||||||
if (gi.args.args[j].type == DIRREF) {
|
if (gi.args.args[j].type == DIRREF) {
|
||||||
addVtVariable(&varTable, gi.args.args[j].value.refName);
|
addVtVariable(&varTable, gi.args.args[j].value.refName, getInstructionReturnType(&gi, &varTable));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ char* compileGroundProgram(GroundProgram* program);
|
|||||||
typedef struct VariableInfo {
|
typedef struct VariableInfo {
|
||||||
char name[256];
|
char name[256];
|
||||||
int offset;
|
int offset;
|
||||||
|
GroundValueType type;
|
||||||
} VariableInfo;
|
} VariableInfo;
|
||||||
|
|
||||||
typedef struct VariableTable {
|
typedef struct VariableTable {
|
||||||
|
|||||||
Reference in New Issue
Block a user