|
@@ -1,12 +1,14 @@
|
|
|
#include <setjmp.h>
|
|
|
#include <stdarg.h>
|
|
|
#include <stdio.h>
|
|
|
+#include <stdlib.h>
|
|
|
#include <string.h>
|
|
|
|
|
|
#include "Compiler.h"
|
|
|
#include "DataType.h"
|
|
|
#include "tokenizer/Tokenizer.h"
|
|
|
#include "utils/Functions.h"
|
|
|
+#include "utils/Structs.h"
|
|
|
#include "utils/Variables.h"
|
|
|
#include "vm/Operation.h"
|
|
|
|
|
@@ -24,6 +26,7 @@ static int16 line = 1;
|
|
|
static Variables vars;
|
|
|
static Functions functions;
|
|
|
static Functions functionQueue;
|
|
|
+static Structs structs;
|
|
|
|
|
|
static int returns[RETURN_BUFFER];
|
|
|
static int returnIndex = 0;
|
|
@@ -537,6 +540,26 @@ static void cAddPostLineChange(Variable* v, int change, const char* name) {
|
|
|
cAddInt(v->address);
|
|
|
}
|
|
|
|
|
|
+static void cDeclareStruct(Struct* st) {
|
|
|
+ cConsumeToken(T_LITERAL);
|
|
|
+ const char* var = cReadString();
|
|
|
+ Variable* v = vSearchScope(&vars, var);
|
|
|
+ if(v != NULL) {
|
|
|
+ cDeclared(var);
|
|
|
+ }
|
|
|
+ vAdd(&vars, var, dtStruct(st->id));
|
|
|
+ int varLength = strlen(var);
|
|
|
+ for(int i = 0; i < st->amount; i++) {
|
|
|
+ int length = strlen(st->vars[i].name);
|
|
|
+ char* fullName = malloc(varLength + length + 2);
|
|
|
+ memcpy(fullName, var, varLength);
|
|
|
+ fullName[varLength] = '.';
|
|
|
+ memcpy(fullName + varLength + 1, st->vars[i].name, length + 1);
|
|
|
+ vAdd(&vars, fullName, st->vars[i].type);
|
|
|
+ free(fullName);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
static void cLineLiteral() {
|
|
|
const char* literal = cReadString();
|
|
|
if(cConsumeTokenIf(T_OPEN_BRACKET)) {
|
|
@@ -546,6 +569,11 @@ static void cLineLiteral() {
|
|
|
}
|
|
|
return;
|
|
|
}
|
|
|
+ Struct* st = stsSearch(&structs, literal);
|
|
|
+ if(st != NULL) {
|
|
|
+ cDeclareStruct(st);
|
|
|
+ return;
|
|
|
+ }
|
|
|
Variable* v = vSearch(&vars, literal);
|
|
|
if(v == NULL) {
|
|
|
cNotDeclared(literal);
|
|
@@ -926,12 +954,39 @@ static void cFunction(DataType rType) {
|
|
|
cSetInt(end, code->length);
|
|
|
}
|
|
|
|
|
|
+static void cStruct() {
|
|
|
+ cConsumeToken(T_LITERAL);
|
|
|
+ const char* name = cReadString();
|
|
|
+ if(stsSearch(&structs, name) != NULL) {
|
|
|
+ cError("struct registered twice");
|
|
|
+ }
|
|
|
+ Struct* st = stsAdd(&structs, name);
|
|
|
+ cConsumeToken(T_OPEN_CURVED_BRACKET);
|
|
|
+ while(!cConsumeTokenIf(T_CLOSE_CURVED_BRACKET)) {
|
|
|
+ Token t = cReadTokenAndLine();
|
|
|
+ DataType dt = DT_VOID;
|
|
|
+ switch(t) {
|
|
|
+ case T_INT: dt = DT_INT; break;
|
|
|
+ case T_BOOL: dt = DT_BOOL; break;
|
|
|
+ case T_FLOAT: dt = DT_FLOAT; break;
|
|
|
+ default: cUnexpectedToken(t);
|
|
|
+ }
|
|
|
+ dt = cDimension(dt);
|
|
|
+ cConsumeToken(T_LITERAL);
|
|
|
+ const char* name = cReadString();
|
|
|
+ stAddVariable(st, name, dt);
|
|
|
+ cConsumeToken(T_SEMICOLON);
|
|
|
+ }
|
|
|
+ cConsumeToken(T_SEMICOLON);
|
|
|
+}
|
|
|
+
|
|
|
static void cGlobalScope(Token t) {
|
|
|
switch(t) {
|
|
|
case T_VOID: cFunction(DT_VOID); break;
|
|
|
case T_INT: cFunction(DT_INT); break;
|
|
|
case T_BOOL: cFunction(DT_BOOL); break;
|
|
|
case T_FLOAT: cFunction(DT_FLOAT); break;
|
|
|
+ case T_STRUCT: cStruct(); break;
|
|
|
default: cUnexpectedToken(t);
|
|
|
}
|
|
|
}
|
|
@@ -979,10 +1034,12 @@ static void cAllocAndCompile() {
|
|
|
vInit(&vars);
|
|
|
fsInit(&functions);
|
|
|
fsInit(&functionQueue);
|
|
|
+ stsInit(&structs);
|
|
|
if(!setjmp(errorJump)) {
|
|
|
cForEachLine();
|
|
|
cLinkQueuedFunctions();
|
|
|
}
|
|
|
+ stsDelete(&structs);
|
|
|
fsDelete(&functionQueue);
|
|
|
fsDelete(&functions);
|
|
|
vDelete(&vars);
|