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;
|
||||
}
|
||||
|
||||
void addVtVariable(VariableTable* vt, const char* name) {
|
||||
void addVtVariable(VariableTable* vt, const char* name, GroundValueType type) {
|
||||
// check if it already exists
|
||||
for (size_t i = 0; i < vt->count; i++) {
|
||||
if (strcmp(vt->vars[i].name, name) == 0) {
|
||||
@@ -29,10 +29,20 @@ void addVtVariable(VariableTable* vt, const char* name) {
|
||||
|
||||
// add the variable
|
||||
strcpy(vt->vars[vt->count].name, name);
|
||||
vt->vars[vt->count].type = type;
|
||||
vt->vars[vt->count].offset = vt->count * 8;
|
||||
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) {
|
||||
for (size_t i = 0; i < vt->count; i++) {
|
||||
if (strcmp(vt->vars[i].name, name) == 0) {
|
||||
@@ -42,6 +52,232 @@ int getVariablePos(VariableTable* vt, const char* name) {
|
||||
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) {
|
||||
if (arg.type == VALREF) {
|
||||
char* buf = malloc(sizeof(char) * 260);
|
||||
@@ -124,7 +360,7 @@ char* compileGroundProgram(GroundProgram* program) {
|
||||
GroundInstruction gi = program->instructions[i];
|
||||
for (size_t j = 0; j < gi.args.length; j++) {
|
||||
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 {
|
||||
char name[256];
|
||||
int offset;
|
||||
GroundValueType type;
|
||||
} VariableInfo;
|
||||
|
||||
typedef struct VariableTable {
|
||||
|
||||
Reference in New Issue
Block a user