Compare commits

7 Commits

7 changed files with 156 additions and 25 deletions

View File

@@ -1,5 +1,6 @@
#ifndef LIBGROUND_H #ifndef LIBGROUND_H
#define LIBGROUND_H #define LIBGROUND_H
#define MAX_ID_LEN 64
/* /*
* groundvm.h * groundvm.h
@@ -13,8 +14,9 @@
#include <stdarg.h> #include <stdarg.h>
#include <uthash.h> #include <uthash.h>
typedef enum GroundInstType { typedef enum GroundInstType {
IF, JUMP, END, INPUT, PRINT, PRINTLN, SET, GETTYPE, EXISTS, SETLIST, SETLISTAT, GETLISTAT, GETLISTSIZE, LISTAPPEND, GETSTRSIZE, GETSTRCHARAT, ADD, SUBTRACT, MULTIPLY, DIVIDE, EQUAL, INEQUAL, NOT, GREATER, LESSER, STOI, STOD, TOSTRING, FUN, RETURN, ENDFUN, PUSHARG, CALL, STRUCT, ENDSTRUCT, INIT, GETFIELD, SETFIELD, USE, EXTERN, CREATELABEL, PAUSE, DROP, ERRORCMD IF, JUMP, END, INPUT, PRINT, PRINTLN, SET, GETTYPE, EXISTS, SETLIST, SETLISTAT, GETLISTAT, GETLISTSIZE, LISTAPPEND, GETSTRSIZE, GETSTRCHARAT, ADD, SUBTRACT, MULTIPLY, DIVIDE, EQUAL, INEQUAL, NOT, GREATER, LESSER, STOI, STOD, ITOC, CTOI, TOSTRING, FUN, RETURN, ENDFUN, PUSHARG, CALL, STRUCT, ENDSTRUCT, INIT, GETFIELD, SETFIELD, USE, EXTERN, CREATELABEL, PAUSE, DROP, ERRORCMD
} GroundInstType; } GroundInstType;
typedef enum GroundValueType { typedef enum GroundValueType {
@@ -164,6 +166,24 @@ typedef struct GroundObject {
GroundObjectField* fields; GroundObjectField* fields;
} GroundObject; } GroundObject;
typedef struct GroundLabel {
char id[MAX_ID_LEN];
int lineNum;
UT_hash_handle hh;
} GroundLabel;
typedef struct GroundVariable {
char id[MAX_ID_LEN];
GroundValue value;
UT_hash_handle hh;
} GroundVariable;
typedef struct GroundScope {
GroundLabel** labels;
GroundVariable** variables;
bool isMainScope;
} GroundScope;
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
@@ -179,6 +199,8 @@ void groundAddValueToInstruction(GroundInstruction* inst, GroundValue value);
void groundAddReferenceToInstruction(GroundInstruction* inst, GroundArg value); void groundAddReferenceToInstruction(GroundInstruction* inst, GroundArg value);
GroundArg groundCreateReference(GroundArgType type, char* ref); GroundArg groundCreateReference(GroundArgType type, char* ref);
void groundAddValueToScope(GroundScope* gs, const char* name, GroundValue value);
GroundValue groundCreateValue(GroundValueType type, ...); GroundValue groundCreateValue(GroundValueType type, ...);
GroundProgram groundParseFile(const char* code); GroundProgram groundParseFile(const char* code);

View File

@@ -5,7 +5,9 @@
#include <inttypes.h> #include <inttypes.h>
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#ifndef _WIN32
#include <dlfcn.h> #include <dlfcn.h>
#endif
#include <stdarg.h> #include <stdarg.h>
#include <unistd.h> #include <unistd.h>
@@ -1126,6 +1128,38 @@ GroundValue interpretGroundInstruction(GroundInstruction inst, GroundScope* scop
addVariable(scope->variables, in->args.args[1].value.refName, createDoubleGroundValue(atof(in->args.args[0].value.value.data.stringVal))); addVariable(scope->variables, in->args.args[1].value.refName, createDoubleGroundValue(atof(in->args.args[0].value.value.data.stringVal)));
break; break;
} }
case ITOC: {
if (in->args.length < 2) {
runtimeError(TOO_FEW_ARGS, "Expecting 2 args", in, currentInstruction);
}
if (in->args.length > 2) {
runtimeError(TOO_MANY_ARGS, "Expecting 2 args", in, currentInstruction);
}
if (in->args.args[0].type != VALUE || in->args.args[0].value.value.type != INT) {
runtimeError(ARG_TYPE_MISMATCH, "Expecting an Int for arg 1", in, currentInstruction);
}
if (in->args.args[1].type != DIRREF) {
runtimeError(ARG_TYPE_MISMATCH, "Expecting a DirectRef for arg 2", in, currentInstruction);
}
addVariable(scope->variables, in->args.args[1].value.refName, createCharGroundValue((char)in->args.args[0].value.value.data.intVal));
break;
}
case CTOI: {
if (in->args.length < 2) {
runtimeError(TOO_FEW_ARGS, "Expecting 2 args", in, currentInstruction);
}
if (in->args.length > 2) {
runtimeError(TOO_MANY_ARGS, "Expecting 2 args", in, currentInstruction);
}
if (in->args.args[0].type != VALUE || in->args.args[0].value.value.type != CHAR) {
runtimeError(ARG_TYPE_MISMATCH, "Expecting a Char for arg 1", in, currentInstruction);
}
if (in->args.args[1].type != DIRREF) {
runtimeError(ARG_TYPE_MISMATCH, "Expecting a DirectRef for arg 2", in, currentInstruction);
}
addVariable(scope->variables, in->args.args[1].value.refName, createIntGroundValue((int)in->args.args[0].value.value.data.charVal));
break;
}
case TOSTRING: { case TOSTRING: {
if (in->args.length < 2) { if (in->args.length < 2) {
runtimeError(TOO_FEW_ARGS, "Expecting 2 args", in, currentInstruction); runtimeError(TOO_FEW_ARGS, "Expecting 2 args", in, currentInstruction);
@@ -1893,6 +1927,10 @@ GroundValue interpretGroundInstruction(GroundInstruction inst, GroundScope* scop
} }
case EXTERN: { case EXTERN: {
#ifdef _WIN32
runtimeError(FIXME, "No Windows support for extern, sucker", in, currentInstruction);
#endif
#ifndef _WIN32
if (in->args.length < 1) { if (in->args.length < 1) {
runtimeError(TOO_FEW_ARGS, "Expecting 1 arg", in, currentInstruction); runtimeError(TOO_FEW_ARGS, "Expecting 1 arg", in, currentInstruction);
} }
@@ -1942,6 +1980,7 @@ GroundValue interpretGroundInstruction(GroundInstruction inst, GroundScope* scop
} }
initFn(scope); initFn(scope);
#endif
break; break;
} }

View File

@@ -1,6 +1,7 @@
#include "parser.h" #include "parser.h"
#include "interpreter.h" #include "interpreter.h"
#include "compiler.h" #include "compiler.h"
#include "types.h"
#include <stdio.h> #include <stdio.h>
char* getFileContents(const char* filename) { char* getFileContents(const char* filename) {
@@ -40,19 +41,6 @@ char* getFileContents(const char* filename) {
} }
int main(int argc, char** argv) { int main(int argc, char** argv) {
/*
if (argc < 2) {
printf("Usage: ground [file]\n");
exit(1);
}
char* file = getFileContents(argv[1]);
GroundProgram program = parseFile(file);
free(file);
char* compiled = compileGroundProgram(&program);
printf("%s\n", compiled);
interpretGroundProgram(&program, NULL);
*/
if (argc < 2) { if (argc < 2) {
printf("Usage: %s <file> [-c] [--compile] [-h] [--help]\n", argv[0]); printf("Usage: %s <file> [-c] [--compile] [-h] [--help]\n", argv[0]);
exit(1); exit(1);
@@ -60,7 +48,7 @@ int main(int argc, char** argv) {
bool compile = false; bool compile = false;
char* fileName = NULL; char* fileName = NULL;
List groundArgs = createList();
for (int i = 1; i < argc; i++) { for (int i = 1; i < argc; i++) {
if (strcmp("--compile", argv[i]) == 0 || strcmp("-c", argv[i]) == 0) { if (strcmp("--compile", argv[i]) == 0 || strcmp("-c", argv[i]) == 0) {
compile = true; compile = true;
@@ -73,7 +61,11 @@ int main(int argc, char** argv) {
printf(" -h or --help: Shows this help message\n"); printf(" -h or --help: Shows this help message\n");
exit(0); exit(0);
} else { } else {
fileName = argv[i]; if (fileName == NULL) {
fileName = argv[i];
} else {
appendToList(&groundArgs, createStringGroundValue(argv[i]));
}
} }
} }
@@ -91,6 +83,14 @@ int main(int argc, char** argv) {
char* compiled = compileGroundProgram(&program); char* compiled = compileGroundProgram(&program);
printf("%s\n", compiled); printf("%s\n", compiled);
} else { } else {
interpretGroundProgram(&program, NULL); GroundVariable* variables = NULL;
GroundLabel* labels = NULL;
GroundScope scope;
scope.variables = &variables;
scope.labels = &labels;
scope.isMainScope = true;
addVariable(scope.variables, "CMDLINE_ARGS", createListGroundValue(groundArgs));
interpretGroundProgram(&program, &scope);
} }
} }

View File

@@ -5,6 +5,25 @@
#include <string.h> #include <string.h>
#include <ctype.h> #include <ctype.h>
#ifdef _WIN32
size_t strnlen(const char *src, size_t n) {
size_t len = 0;
while (len < n && src[len])
len++;
return len;
}
char* strndup(const char *s, size_t n) {
size_t len = strnlen(s, n);
char *p = malloc(len + 1);
if (p) {
memcpy(p, s, len);
p[len] = '\0';
}
return p;
}
#endif
GroundProgram createGroundProgram() { GroundProgram createGroundProgram() {
GroundProgram gp; GroundProgram gp;
gp.size = 0; gp.size = 0;
@@ -159,6 +178,8 @@ static GroundInstType getInstructionType(const char* inst) {
if (strcmp(inst, "lesser") == 0) return LESSER; if (strcmp(inst, "lesser") == 0) return LESSER;
if (strcmp(inst, "stoi") == 0) return STOI; if (strcmp(inst, "stoi") == 0) return STOI;
if (strcmp(inst, "stod") == 0) return STOD; if (strcmp(inst, "stod") == 0) return STOD;
if (strcmp(inst, "ctoi") == 0) return CTOI;
if (strcmp(inst, "itoc") == 0) return ITOC;
if (strcmp(inst, "tostring") == 0) return TOSTRING; if (strcmp(inst, "tostring") == 0) return TOSTRING;
if (strcmp(inst, "fun") == 0) return FUN; if (strcmp(inst, "fun") == 0) return FUN;
if (strcmp(inst, "return") == 0) return RETURN; if (strcmp(inst, "return") == 0) return RETURN;

View File

@@ -90,16 +90,55 @@ GroundValue copyGroundValue(const GroundValue* gv) {
} }
case FUNCTION: newGv.data.fnVal = gv->data.fnVal; break; case FUNCTION: newGv.data.fnVal = gv->data.fnVal; break;
case STRUCTVAL: { case STRUCTVAL: {
// do this later lmao newGv.data.structVal = malloc(sizeof(GroundStruct));
// FIXME if (newGv.data.structVal == NULL) {
newGv.data.structVal = gv->data.structVal; printf("Couldn't allocate memory for GroundStruct copy\n");
exit(1);
}
newGv.data.structVal->size = gv->data.structVal->size;
newGv.data.structVal->fields = malloc(gv->data.structVal->size * sizeof(GroundStructField));
if (newGv.data.structVal->fields == NULL && gv->data.structVal->size > 0) {
printf("Couldn't allocate memory for GroundStruct fields copy\n");
exit(1);
}
for (size_t i = 0; i < gv->data.structVal->size; i++) {
strncpy(newGv.data.structVal->fields[i].id,
gv->data.structVal->fields[i].id,
sizeof(newGv.data.structVal->fields[i].id) - 1);
newGv.data.structVal->fields[i].id[sizeof(newGv.data.structVal->fields[i].id) - 1] = '\0';
newGv.data.structVal->fields[i].value = copyGroundValue(&gv->data.structVal->fields[i].value);
}
break; break;
} }
case CUSTOM: case CUSTOM: {
// also do this later newGv.customType = gv->customType;
// FIXME newGv.data.customVal = malloc(sizeof(GroundObject));
newGv.data.customVal = gv->data.customVal; if (newGv.data.customVal == NULL) {
printf("Couldn't allocate memory for GroundObject copy\n");
exit(1);
}
newGv.data.customVal->fields = NULL;
GroundObjectField *field, *tmp;
HASH_ITER(hh, gv->data.customVal->fields, field, tmp) {
GroundObjectField* newField = malloc(sizeof(GroundObjectField));
if (newField == NULL) {
printf("Couldn't allocate memory for GroundObjectField copy\n");
exit(1);
}
strncpy(newField->id, field->id, sizeof(newField->id) - 1);
newField->id[sizeof(newField->id) - 1] = '\0';
newField->value = copyGroundValue(&field->value);
HASH_ADD_STR(newGv.data.customVal->fields, id, newField);
}
break; break;
}
case NONE: case NONE:
default: { default: {
@@ -413,6 +452,12 @@ void printGroundInstruction(GroundInstruction* gi) {
case STOD: case STOD:
printf("stod"); printf("stod");
break; break;
case CTOI:
printf("ctoi");
break;
case ITOC:
printf("itoc");
break;
case TOSTRING: case TOSTRING:
printf("tostring"); printf("tostring");
break; break;

View File

@@ -9,7 +9,7 @@
#include "include/uthash.h" #include "include/uthash.h"
typedef enum GroundInstType { typedef enum GroundInstType {
IF, JUMP, END, INPUT, PRINT, PRINTLN, SET, GETTYPE, EXISTS, SETLIST, SETLISTAT, GETLISTAT, GETLISTSIZE, LISTAPPEND, GETSTRSIZE, GETSTRCHARAT, ADD, SUBTRACT, MULTIPLY, DIVIDE, EQUAL, INEQUAL, NOT, GREATER, LESSER, STOI, STOD, TOSTRING, FUN, RETURN, ENDFUN, PUSHARG, CALL, STRUCT, ENDSTRUCT, INIT, GETFIELD, SETFIELD, USE, EXTERN, CREATELABEL, PAUSE, DROP, ERRORCMD IF, JUMP, END, INPUT, PRINT, PRINTLN, SET, GETTYPE, EXISTS, SETLIST, SETLISTAT, GETLISTAT, GETLISTSIZE, LISTAPPEND, GETSTRSIZE, GETSTRCHARAT, ADD, SUBTRACT, MULTIPLY, DIVIDE, EQUAL, INEQUAL, NOT, GREATER, LESSER, STOI, STOD, ITOC, CTOI, TOSTRING, FUN, RETURN, ENDFUN, PUSHARG, CALL, STRUCT, ENDSTRUCT, INIT, GETFIELD, SETFIELD, USE, EXTERN, CREATELABEL, PAUSE, DROP, ERRORCMD
} GroundInstType; } GroundInstType;
typedef enum GroundValueType { typedef enum GroundValueType {

View File

@@ -1,7 +1,11 @@
tostring 32 &str tostring 32 &str
stoi "12" &int stoi "12" &int
stod "3.14" &dou stod "3.14" &dou
itoc 353 &chr
ctoi 'a' &it2
println $str println $str
println $int println $int
println $dou println $dou
println $chr
println $it2