Start working on allowing more types in compiler

This commit is contained in:
2026-01-22 14:10:26 +11:00
parent 955e75addb
commit 0c2abbae2f
2 changed files with 239 additions and 2 deletions

View File

@@ -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));
} }
} }
} }

View File

@@ -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 {