Clean compiler-scopes.c
This commit is contained in:
parent
2e48e42368
commit
6578c9d7eb
|
@ -3,25 +3,13 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "compiler-scopes.h"
|
#include "compiler-scopes.h"
|
||||||
|
|
||||||
// INTERNAL FUNCTIONS
|
|
||||||
// Information gathering
|
|
||||||
bool existstr(STRINGLIST* strs, const char* str);
|
|
||||||
bool existclass(CLASS* c, const char* name);
|
|
||||||
DEBUGINFO* getdebuginfo(OBJ* obj);
|
|
||||||
|
|
||||||
// Error messages
|
// Error messages
|
||||||
void doubledeclaration(const char* name, DEBUGINFO* debug, OBJ* other);
|
void doubledeclaration(const char* name, OBJ* o1, OBJ* o2);
|
||||||
void ensurenoduplicate(SCOPE* s, const char* name, DEBUGINFO* debug);
|
void ensurenoduplicate(SCOPE* s, OBJ* o);
|
||||||
|
|
||||||
// Scope handling
|
|
||||||
void popscope(SCOPE** s); // may be removed
|
|
||||||
|
|
||||||
// Single type getters
|
|
||||||
VARDEC* getvardec(SCOPE* s, const char* name);
|
|
||||||
CLASSVARDEC* getclassvardec(SCOPE* s, const char* name);
|
|
||||||
|
|
||||||
// Generic getters
|
// Generic getters
|
||||||
OBJ* getbynamelist(SCOPE* s, STRINGLIST* names, const char** retname);
|
OBJ* getbynamelist(SCOPE* s, STRINGLIST* names, const char** retname);
|
||||||
|
OBJ* getbynamewithtype(SCOPE* s, const char* name, OBJTYPE type);
|
||||||
|
|
||||||
// Scope adding
|
// Scope adding
|
||||||
void addclassvardec(SCOPE* s, CLASSVARDEC* v);
|
void addclassvardec(SCOPE* s, CLASSVARDEC* v);
|
||||||
|
@ -29,58 +17,20 @@ void addvardec(SCOPE* s, VARDEC* v);
|
||||||
void addsubroutdec(SCOPE* s, SUBROUTDEC* sd);
|
void addsubroutdec(SCOPE* s, SUBROUTDEC* sd);
|
||||||
void addclass(SCOPE* s, CLASS* c);
|
void addclass(SCOPE* s, CLASS* c);
|
||||||
|
|
||||||
// DEFINITIONS
|
|
||||||
// Information gathering
|
|
||||||
bool existstr(STRINGLIST* strs, const char* str) {
|
|
||||||
while(strs != NULL) {
|
|
||||||
if(!strcmp(strs->content, str))
|
|
||||||
return true;
|
|
||||||
strs = strs->next;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool existclass(CLASS* c, const char* name) {
|
|
||||||
while(c != NULL) {
|
|
||||||
if(!strcmp(c->name, name))
|
|
||||||
return true;
|
|
||||||
c = c->next;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// OBJ handling
|
// OBJ handling
|
||||||
|
|
||||||
DEBUGINFO* getdebugclassvardec(OBJ* obj) {
|
|
||||||
return obj->classvardec->base->debug;
|
|
||||||
}
|
|
||||||
|
|
||||||
DEBUGINFO* getdebugvardec(OBJ* obj) {
|
|
||||||
return obj->vardec->debug;
|
|
||||||
}
|
|
||||||
|
|
||||||
DEBUGINFO* getdebugsubroutdec(OBJ* obj) {
|
|
||||||
return obj->subroutdec->debug;
|
|
||||||
}
|
|
||||||
|
|
||||||
DEBUGINFO* getdebugclass(OBJ* obj) {
|
|
||||||
return obj->class->debug;
|
|
||||||
}
|
|
||||||
|
|
||||||
VARDEC* tovardec(OBJ* obj) {
|
VARDEC* tovardec(OBJ* obj) {
|
||||||
if (obj->type == classvardec)
|
if (obj->type == classvardec)
|
||||||
return obj->classvardec->base;
|
return ((CLASSVARDEC*)(obj->pointer))->base;
|
||||||
else if (obj->type == vardec)
|
else if (obj->type == vardec)
|
||||||
return obj->vardec;
|
return (VARDEC*)(obj->pointer);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Error messages
|
// Error messages
|
||||||
|
void doubledeclaration(const char* name, OBJ* o1, OBJ* o2) {
|
||||||
void doubledeclaration(const char* name, DEBUGINFO* debug, OBJ* other) {
|
|
||||||
DEBUGINFO* debugother = other->getdebug(other);
|
|
||||||
eprintf("Double declaration of '%s' at '%s', line %i; previously defined at '%s', line %i\n",
|
eprintf("Double declaration of '%s' at '%s', line %i; previously defined at '%s', line %i\n",
|
||||||
name, debug->file, debug->definedat, debugother->file, debugother->definedat);
|
name, o1->debug->file, o1->debug->definedat, o2->debug->file, o2->debug->definedat);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -94,85 +44,30 @@ void invalidparent(SUBROUTCALL* call) {
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ensurenoduplicate(SCOPE* s, const char* name, DEBUGINFO* debug) {
|
void ensurenoduplicate(SCOPE* s, OBJ* o) {
|
||||||
OBJ* other = getbyname(s, name);
|
|
||||||
if(other != NULL)
|
|
||||||
doubledeclaration(name, debug, other);
|
|
||||||
}
|
|
||||||
|
|
||||||
void ensurenoduplicates(SCOPE* s, STRINGLIST* names, DEBUGINFO* debug) {
|
|
||||||
const char* othername;
|
const char* othername;
|
||||||
OBJ* other = getbynamelist(s, names, &othername);
|
OBJ* other = getbynamelist(s, o->names, &othername);
|
||||||
if(other != NULL)
|
if(other != NULL)
|
||||||
doubledeclaration(othername, debug, other);
|
doubledeclaration(othername, o, other);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Scope handling
|
// Scope handling
|
||||||
|
|
||||||
SCOPE* mkscope(SCOPE* prev) {
|
SCOPE* mkscope(SCOPE* prev) {
|
||||||
SCOPE* s = (SCOPE*)malloc(sizeof(SCOPE));
|
SCOPE* s = (SCOPE*)malloc(sizeof(SCOPE));
|
||||||
s->subroutines = NULL;
|
s->objects = NULL;
|
||||||
s->classvardecs = NULL;
|
|
||||||
s->vardecs = NULL;
|
|
||||||
s->classes = NULL;
|
|
||||||
s->previous = prev;
|
s->previous = prev;
|
||||||
s->condlabelcount = 0;
|
s->condlabelcount = 0;
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
void popscope(SCOPE** s) { // might be useless
|
|
||||||
SCOPE* prev = (*s)->previous;
|
|
||||||
free(*s);
|
|
||||||
(*s) = prev;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Single type getters
|
// Single type getters
|
||||||
VARDEC* getvardec(SCOPE* s, const char* name) {
|
|
||||||
VARDEC* curr = s->vardecs;
|
|
||||||
while(curr != NULL) {
|
|
||||||
if(existstr(curr->names, name))
|
|
||||||
return curr;
|
|
||||||
curr = curr->next;
|
|
||||||
}
|
|
||||||
if(s->previous != NULL)
|
|
||||||
return getvardec(s->previous, name);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
CLASSVARDEC* getclassvardec(SCOPE* s, const char* name) {
|
|
||||||
CLASSVARDEC* curr = s->classvardecs;
|
|
||||||
while(curr != NULL) {
|
|
||||||
if(existstr(curr->base->names, name))
|
|
||||||
return curr;
|
|
||||||
curr = curr->next;
|
|
||||||
}
|
|
||||||
if(s->previous != NULL)
|
|
||||||
return getclassvardec(s->previous, name);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
SUBROUTDEC* getsubroutdec(SCOPE* s, const char* name) {
|
SUBROUTDEC* getsubroutdec(SCOPE* s, const char* name) {
|
||||||
SUBROUTDEC* curr = s->subroutines;
|
return (SUBROUTDEC*)(getbynamewithtype(s, name, subroutdec)->pointer);
|
||||||
while(curr != NULL) {
|
|
||||||
if(!strcmp(curr->name, name))
|
|
||||||
return curr;
|
|
||||||
curr = curr->next;
|
|
||||||
}
|
|
||||||
if(s->previous != NULL)
|
|
||||||
return getsubroutdec(s->previous, name);
|
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
CLASS* getclass(SCOPE* s, const char* name) {
|
CLASS* getclass(SCOPE* s, const char* name) {
|
||||||
CLASS* curr = s->classes;
|
return (CLASS*)(getbynamewithtype(s, name, class)->pointer);
|
||||||
while(curr != NULL) {
|
|
||||||
if(!strcmp(curr->name, name))
|
|
||||||
return curr;
|
|
||||||
curr = curr->next;
|
|
||||||
}
|
|
||||||
if(s->previous != NULL)
|
|
||||||
return getclass(s->previous, name);
|
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SUBROUTDEC* getsubroutdecfromclass(CLASS* c, const char* name) {
|
SUBROUTDEC* getsubroutdecfromclass(CLASS* c, const char* name) {
|
||||||
|
@ -201,7 +96,7 @@ SUBROUTDEC* getsubroutdecfromparent(SCOPE* s, SUBROUTCALL* call) {
|
||||||
notdeclared(call->parentname, call->debug);
|
notdeclared(call->parentname, call->debug);
|
||||||
|
|
||||||
if(parent->type == class)
|
if(parent->type == class)
|
||||||
sd = getsubroutdecfromclass(parent->class, call->name);
|
sd = getsubroutdecfromclass(parent->pointer, call->name);
|
||||||
else
|
else
|
||||||
sd = getsubroutdecfromvar(s, parent, call);
|
sd = getsubroutdecfromvar(s, parent, call);
|
||||||
return sd;
|
return sd;
|
||||||
|
@ -219,121 +114,88 @@ SUBROUTDEC* getsubroutdecfromcall(SCOPE* s, SUBROUTCALL* call) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generic getters
|
// Generic getters
|
||||||
OBJ* getbyname(SCOPE* s, const char* name) {
|
|
||||||
OBJ* o = (OBJ*)malloc(sizeof(OBJ));
|
|
||||||
|
|
||||||
CLASSVARDEC* cvd = getclassvardec(s, name);
|
|
||||||
if(cvd != NULL) {
|
|
||||||
o->classvardec = cvd;
|
|
||||||
o->type = classvardec;
|
|
||||||
o->getdebug = getdebugvardec;
|
|
||||||
return o;
|
|
||||||
}
|
|
||||||
|
|
||||||
VARDEC* vd = getvardec(s, name);
|
|
||||||
if(vd != NULL) {
|
|
||||||
o->vardec = vd;
|
|
||||||
o->type = vardec;
|
|
||||||
o->getdebug = getdebugsubroutdec;
|
|
||||||
return o;
|
|
||||||
}
|
|
||||||
|
|
||||||
SUBROUTDEC* sd = getsubroutdec(s, name);
|
|
||||||
if(sd != NULL) {
|
|
||||||
o->subroutdec = sd;
|
|
||||||
o->type = subroutdec;
|
|
||||||
o->getdebug = getdebugclassvardec;
|
|
||||||
return o;
|
|
||||||
}
|
|
||||||
|
|
||||||
CLASS* c = getclass(s, name);
|
|
||||||
if(c != NULL) {
|
|
||||||
o->class = c;
|
|
||||||
o->type = class;
|
|
||||||
o->getdebug = getdebugclass;
|
|
||||||
return o;
|
|
||||||
}
|
|
||||||
|
|
||||||
free(o);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
OBJ* getbynamelist(SCOPE* s, STRINGLIST* names, const char** retname) {
|
OBJ* getbynamelist(SCOPE* s, STRINGLIST* names, const char** retname) {
|
||||||
while(names != NULL) {
|
OBJ* curr = s->objects;
|
||||||
OBJ* o = getbyname(s, names->content);
|
while(curr != NULL) {
|
||||||
if(o != NULL) {
|
STRINGLIST* currn = curr->names;
|
||||||
*retname = names->content;
|
while(currn != NULL) {
|
||||||
return o;
|
STRINGLIST* currattempt = names;
|
||||||
|
while(currattempt != NULL) {
|
||||||
|
if(!strcmp(currn->content, currattempt->content)) {
|
||||||
|
*retname = currn->content;
|
||||||
|
return curr;
|
||||||
}
|
}
|
||||||
names = names->next;
|
currattempt = currattempt->next;
|
||||||
|
}
|
||||||
|
currn = currn->next;
|
||||||
|
}
|
||||||
|
curr = curr->next;
|
||||||
}
|
}
|
||||||
if(s->previous != NULL)
|
if(s->previous != NULL)
|
||||||
return getbynamelist(s->previous, names, retname);
|
return getbynamelist(s->previous, names, retname);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
OBJ* getbyname(SCOPE* s, const char* name) {
|
||||||
|
STRINGLIST* onename = onestr(name);
|
||||||
|
const char* dummy;
|
||||||
|
return getbynamelist(s, onename, &dummy);
|
||||||
|
}
|
||||||
|
|
||||||
|
OBJ* getbynamewithtype(SCOPE* s, const char* name, OBJTYPE type) {
|
||||||
|
OBJ* o = getbyname(s, name);
|
||||||
|
if(o->type != type)
|
||||||
|
notdeclared(name, o->debug);
|
||||||
|
return o;
|
||||||
|
}
|
||||||
|
|
||||||
// Scope adding
|
// Scope adding
|
||||||
void addclassvardec(SCOPE* s, CLASSVARDEC* v) {
|
void addobj(SCOPE* s, OBJ* o) {
|
||||||
ensurenoduplicates(s, v->base->names, v->base->debug);
|
ensurenoduplicate(s, o);
|
||||||
CLASSVARDEC* new = copy(v, sizeof(CLASSVARDEC));
|
o->next = s->objects;
|
||||||
new->next = s->classvardecs;
|
s->objects = o;
|
||||||
s->classvardecs = new;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void addvardec(SCOPE* s, VARDEC* v) {
|
OBJ* mkobj(void* pointer, OBJTYPE type, DEBUGINFO* debug, STRINGLIST* names) {
|
||||||
ensurenoduplicates(s, v->names, v->debug);
|
OBJ* o = (OBJ*)malloc(sizeof(OBJ));
|
||||||
VARDEC* new = copy(v, sizeof(VARDEC));
|
o->pointer = pointer;
|
||||||
new->next = s->vardecs;
|
o->type = type;
|
||||||
s->vardecs = new;
|
o->debug = debug;
|
||||||
|
o->names = names;
|
||||||
|
return o;
|
||||||
}
|
}
|
||||||
|
|
||||||
void addsubroutdec(SCOPE* s, SUBROUTDEC* sd) {
|
void addany(SCOPE* s, void* pointer, OBJTYPE type, DEBUGINFO* debug, STRINGLIST* names) {
|
||||||
ensurenoduplicate(s, sd->name, sd->debug);
|
addobj(s, mkobj(pointer, type, debug, names));
|
||||||
SUBROUTDEC* new = copy(sd, sizeof(SUBROUTDEC));
|
|
||||||
new->next = s->subroutines;
|
|
||||||
s->subroutines = new;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void addclass(SCOPE* s, CLASS* c) {
|
void addclassvardecs(SCOPE* s, CLASSVARDEC* v) {
|
||||||
ensurenoduplicate(s, c->name, c->debug);
|
addany(s, v, classvardec, v->base->debug, v->base->names);
|
||||||
CLASS* new = copy(c, sizeof(CLASS));
|
if(v->next != NULL)
|
||||||
new->next = s->classes;
|
addclassvardecs(s, v->next);
|
||||||
s->classes = new;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Group adding
|
void addvardecs(SCOPE* s, VARDEC* v) {
|
||||||
void addclassvardecs(SCOPE* s, CLASSVARDEC* vs) {
|
addany(s, v, vardec, v->debug, v->names);
|
||||||
CLASSVARDEC* next;
|
if(v->next != NULL)
|
||||||
while(vs != NULL) {
|
addvardecs(s, v->next);
|
||||||
next = vs->next;
|
|
||||||
addclassvardec(s, vs);
|
|
||||||
vs = next;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void addvardecs(SCOPE* s, VARDEC* vs) {
|
void addsubroutdecs(SCOPE* s, SUBROUTDEC* sd) {
|
||||||
VARDEC* next;
|
addany(s, sd, subroutdec, sd->debug, onestr(sd->name));
|
||||||
while(vs != NULL) {
|
if(sd->next != NULL)
|
||||||
next = vs->next;
|
addsubroutdecs(s, sd->next);
|
||||||
addvardec(s, vs);
|
|
||||||
vs = next;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void addsubroutdecs(SCOPE* s, SUBROUTDEC* ss) {
|
|
||||||
SUBROUTDEC* next;
|
|
||||||
while(ss != NULL) {
|
|
||||||
next = ss->next;
|
|
||||||
addsubroutdec(s, ss);
|
|
||||||
ss = next;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void addclasses(SCOPE* s, CLASS* c) {
|
void addclasses(SCOPE* s, CLASS* c) {
|
||||||
CLASS* next;
|
addany(s, c, class, c->debug, onestr(c->name));
|
||||||
while(c != NULL) {
|
if(c->next != NULL)
|
||||||
next = c->next;
|
addclasses(s, c->next);
|
||||||
addclass(s, c);
|
|
||||||
c = next;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void addparameters(SCOPE* s, PARAMETER* p) {
|
||||||
|
addany(s, p, parameter, p->debug, onestr(p->name));
|
||||||
|
if(p->next != NULL)
|
||||||
|
addparameters(s, p->next);
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,35 +9,30 @@
|
||||||
* certain semantic rules. */
|
* certain semantic rules. */
|
||||||
|
|
||||||
// Data types
|
// Data types
|
||||||
typedef struct scope {
|
|
||||||
SUBROUTDEC* subroutines;
|
|
||||||
CLASSVARDEC* classvardecs;
|
|
||||||
VARDEC* vardecs;
|
|
||||||
CLASS* classes;
|
|
||||||
int condlabelcount;
|
|
||||||
struct scope* previous;
|
|
||||||
} SCOPE;
|
|
||||||
|
|
||||||
typedef enum {
|
typedef enum {
|
||||||
subroutdec, classvardec, vardec, class
|
subroutdec, classvardec, vardec, class, parameter
|
||||||
} OBJTYPE;
|
} OBJTYPE;
|
||||||
|
|
||||||
typedef struct object {
|
typedef struct object {
|
||||||
|
void* pointer;
|
||||||
|
DEBUGINFO* debug;
|
||||||
|
STRINGLIST* names;
|
||||||
OBJTYPE type;
|
OBJTYPE type;
|
||||||
union {
|
struct object* next;
|
||||||
SUBROUTDEC* subroutdec;
|
|
||||||
CLASSVARDEC* classvardec;
|
|
||||||
VARDEC* vardec;
|
|
||||||
CLASS* class;
|
|
||||||
};
|
|
||||||
DEBUGINFO* (*getdebug)(struct object*);
|
|
||||||
} OBJ;
|
} OBJ;
|
||||||
|
|
||||||
|
typedef struct scope {
|
||||||
|
OBJ* objects;
|
||||||
|
int condlabelcount;
|
||||||
|
struct scope* previous;
|
||||||
|
} SCOPE;
|
||||||
|
|
||||||
// Group adding
|
// Group adding
|
||||||
void addclassvardecs(SCOPE* s, CLASSVARDEC* vs);
|
void addclassvardecs(SCOPE* s, CLASSVARDEC* vs);
|
||||||
void addvardecs(SCOPE* s, VARDEC* vs);
|
void addvardecs(SCOPE* s, VARDEC* vs);
|
||||||
void addsubroutdecs(SCOPE* s, SUBROUTDEC* ss);
|
void addsubroutdecs(SCOPE* s, SUBROUTDEC* ss);
|
||||||
void addclasses(SCOPE* s, CLASS* c);
|
void addclasses(SCOPE* s, CLASS* c);
|
||||||
|
void addparameters(SCOPE* s, PARAMETER* p);
|
||||||
|
|
||||||
// Scope handling
|
// Scope handling
|
||||||
SCOPE* mkscope(SCOPE* prev);
|
SCOPE* mkscope(SCOPE* prev);
|
||||||
|
|
|
@ -257,8 +257,10 @@ LINEBLOCK* compilestatements(SCOPE* s, CLASS* c, STATEMENT* sts) {
|
||||||
}
|
}
|
||||||
|
|
||||||
LINEBLOCK* compilefunbody(SCOPE* s, CLASS* c, SUBROUTBODY* b) {
|
LINEBLOCK* compilefunbody(SCOPE* s, CLASS* c, SUBROUTBODY* b) {
|
||||||
// missing scope and vardecs handling
|
SCOPE* myscope = mkscope(s);
|
||||||
LINEBLOCK* head = compilestatements(s, c, b->statements);
|
if(b->vardecs != NULL)
|
||||||
|
addvardecs(s, b->vardecs);
|
||||||
|
LINEBLOCK* head = compilestatements(myscope, c, b->statements);
|
||||||
return head;
|
return head;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -291,7 +293,9 @@ LINEBLOCK* compilesubroutdec(SCOPE* s, CLASS* c, SUBROUTDEC* sd) {
|
||||||
|
|
||||||
LINEBLOCK* compileclass(COMPILER* c, CLASS* class) {
|
LINEBLOCK* compileclass(COMPILER* c, CLASS* class) {
|
||||||
SCOPE* topscope = mkscope(c->globalscope);
|
SCOPE* topscope = mkscope(c->globalscope);
|
||||||
|
if(class->vardecs != NULL)
|
||||||
addclassvardecs(topscope, class->vardecs);
|
addclassvardecs(topscope, class->vardecs);
|
||||||
|
if(class->subroutdecs != NULL)
|
||||||
addsubroutdecs(topscope, class->subroutdecs);
|
addsubroutdecs(topscope, class->subroutdecs);
|
||||||
|
|
||||||
LINEBLOCK* output = NULL;
|
LINEBLOCK* output = NULL;
|
||||||
|
@ -305,7 +309,7 @@ LINEBLOCK* compileclass(COMPILER* c, CLASS* class) {
|
||||||
|
|
||||||
void compile(COMPILER* c) {
|
void compile(COMPILER* c) {
|
||||||
LINEBLOCK* output = NULL;
|
LINEBLOCK* output = NULL;
|
||||||
CLASS* curr = c->globalscope->classes;
|
CLASS* curr = c->classes;
|
||||||
while(curr != NULL) {
|
while(curr != NULL) {
|
||||||
output = mergelnblks(output, compileclass(c, curr));
|
output = mergelnblks(output, compileclass(c, curr));
|
||||||
curr = curr->next;
|
curr = curr->next;
|
||||||
|
@ -317,5 +321,6 @@ COMPILER* mkcompiler(CLASS* classes) {
|
||||||
COMPILER* c = (COMPILER*)malloc(sizeof(COMPILER));
|
COMPILER* c = (COMPILER*)malloc(sizeof(COMPILER));
|
||||||
c->globalscope = mkscope(NULL);
|
c->globalscope = mkscope(NULL);
|
||||||
addclasses(c->globalscope, classes);
|
addclasses(c->globalscope, classes);
|
||||||
|
c->classes = classes;
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,7 @@
|
||||||
#include "vm-lines.h"
|
#include "vm-lines.h"
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
CLASS* classes;
|
||||||
SCOPE* globalscope;
|
SCOPE* globalscope;
|
||||||
LINEBLOCK* output;
|
LINEBLOCK* output;
|
||||||
} COMPILER;
|
} COMPILER;
|
||||||
|
|
|
@ -87,11 +87,16 @@ CLASSVARDEC* parseclassvardec(PARSER* p) {
|
||||||
|
|
||||||
CLASSVARDEC* parseclassvardecs(PARSER* p) {
|
CLASSVARDEC* parseclassvardecs(PARSER* p) {
|
||||||
CLASSVARDEC* head = parseclassvardec(p);
|
CLASSVARDEC* head = parseclassvardec(p);
|
||||||
|
if(head != NULL)
|
||||||
|
head->base->index = 0;
|
||||||
|
int index = 1;
|
||||||
CLASSVARDEC* curr = head;
|
CLASSVARDEC* curr = head;
|
||||||
CLASSVARDEC* next;
|
CLASSVARDEC* nextc;
|
||||||
while(next = parseclassvardec(p), next != NULL) {
|
while(nextc = parseclassvardec(p), nextc != NULL) {
|
||||||
curr->next = next;
|
nextc->base->index = index;
|
||||||
curr= next;
|
index++;
|
||||||
|
curr->next = nextc;
|
||||||
|
curr = nextc;
|
||||||
}
|
}
|
||||||
if(curr != NULL)
|
if(curr != NULL)
|
||||||
curr->next = NULL;
|
curr->next = NULL;
|
||||||
|
@ -136,10 +141,10 @@ SUBROUTDEC* parsesubroutdec(PARSER* p) {
|
||||||
SUBROUTDEC* parsesubroutdecs(PARSER* p) {
|
SUBROUTDEC* parsesubroutdecs(PARSER* p) {
|
||||||
SUBROUTDEC* head = parsesubroutdec(p);
|
SUBROUTDEC* head = parsesubroutdec(p);
|
||||||
SUBROUTDEC* curr = head;
|
SUBROUTDEC* curr = head;
|
||||||
SUBROUTDEC* next;
|
SUBROUTDEC* nexts;
|
||||||
while(next = parsesubroutdec(p), next != NULL) {
|
while(nexts = parsesubroutdec(p), nexts != NULL) {
|
||||||
curr->next = next;
|
curr->next = nexts;
|
||||||
curr = next;
|
curr = nexts;
|
||||||
}
|
}
|
||||||
if(curr != NULL)
|
if(curr != NULL)
|
||||||
curr->next = NULL;
|
curr->next = NULL;
|
||||||
|
@ -150,6 +155,7 @@ PARAMETER* parseparameter(PARSER* p) {
|
||||||
PARAMETER* param = (PARAMETER*)malloc(sizeof(PARAMETER));
|
PARAMETER* param = (PARAMETER*)malloc(sizeof(PARAMETER));
|
||||||
if(equals(p, ")"))
|
if(equals(p, ")"))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
param->debug = getdebug(p);
|
||||||
param->type = parsetype(p);
|
param->type = parsetype(p);
|
||||||
param->name = parseidentifier(p);
|
param->name = parseidentifier(p);
|
||||||
return param;
|
return param;
|
||||||
|
@ -157,10 +163,19 @@ PARAMETER* parseparameter(PARSER* p) {
|
||||||
|
|
||||||
PARAMETER* parseparameters(PARSER* p) {
|
PARAMETER* parseparameters(PARSER* p) {
|
||||||
PARAMETER* head = parseparameter(p);
|
PARAMETER* head = parseparameter(p);
|
||||||
|
if(head != NULL)
|
||||||
|
head->index = 0;
|
||||||
|
int index = 1;
|
||||||
PARAMETER* curr = head;
|
PARAMETER* curr = head;
|
||||||
|
PARAMETER* nextp;
|
||||||
while(equals(p, ",")) {
|
while(equals(p, ",")) {
|
||||||
next(p);
|
next(p);
|
||||||
curr->next = parseparameter(p);
|
nextp = parseparameter(p);
|
||||||
|
if(nextp == NULL)
|
||||||
|
unexpected(p);
|
||||||
|
nextp->index = index;
|
||||||
|
curr->next = nextp;
|
||||||
|
index++;
|
||||||
curr = curr->next;
|
curr = curr->next;
|
||||||
}
|
}
|
||||||
if(curr != NULL)
|
if(curr != NULL)
|
||||||
|
@ -231,11 +246,16 @@ VARDEC* parsevardec(PARSER* p) {
|
||||||
|
|
||||||
VARDEC* parsevardecs(PARSER* p) {
|
VARDEC* parsevardecs(PARSER* p) {
|
||||||
VARDEC* head = parsevardec(p);
|
VARDEC* head = parsevardec(p);
|
||||||
|
if(head != NULL)
|
||||||
|
head->index = 0;
|
||||||
|
int index = 1;
|
||||||
VARDEC* curr = head;
|
VARDEC* curr = head;
|
||||||
VARDEC* next;
|
VARDEC* nextv;
|
||||||
while(next = parsevardec(p), next != NULL) {
|
while(nextv = parsevardec(p), nextv != NULL) {
|
||||||
curr->next = next;
|
nextv->index = index;
|
||||||
curr = next;
|
index++;
|
||||||
|
curr->next = nextv;
|
||||||
|
curr = nextv;
|
||||||
}
|
}
|
||||||
if(curr != NULL)
|
if(curr != NULL)
|
||||||
curr->next = NULL;
|
curr->next = NULL;
|
||||||
|
|
|
@ -60,6 +60,8 @@ typedef struct subroutdec {
|
||||||
typedef struct parameter {
|
typedef struct parameter {
|
||||||
char* type;
|
char* type;
|
||||||
char* name;
|
char* name;
|
||||||
|
int index;
|
||||||
|
DEBUGINFO* debug;
|
||||||
struct parameter* next;
|
struct parameter* next;
|
||||||
} PARAMETER;
|
} PARAMETER;
|
||||||
|
|
||||||
|
@ -71,10 +73,11 @@ typedef struct subroutbody {
|
||||||
typedef struct vardec {
|
typedef struct vardec {
|
||||||
char* type;
|
char* type;
|
||||||
bool primitive;
|
bool primitive;
|
||||||
|
int index;
|
||||||
TOKENTYPE typeclass;
|
TOKENTYPE typeclass;
|
||||||
STRINGLIST* names;
|
STRINGLIST* names;
|
||||||
struct vardec* next;
|
|
||||||
DEBUGINFO* debug;
|
DEBUGINFO* debug;
|
||||||
|
struct vardec* next;
|
||||||
} VARDEC;
|
} VARDEC;
|
||||||
|
|
||||||
// Statements
|
// Statements
|
||||||
|
|
7
util.c
7
util.c
|
@ -40,6 +40,13 @@ char* itoa(int i) {
|
||||||
return a;
|
return a;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
STRINGLIST* onestr(const char* str) {
|
||||||
|
STRINGLIST* strlist = (STRINGLIST*)malloc(sizeof(STRINGLIST));
|
||||||
|
strlist->content = ezheapstr(str);
|
||||||
|
strlist->next = NULL;
|
||||||
|
return strlist;
|
||||||
|
}
|
||||||
|
|
||||||
STRINGLIST* initstrlist(const char** strs, int count) {
|
STRINGLIST* initstrlist(const char** strs, int count) {
|
||||||
STRINGLIST* strlist = (STRINGLIST*)malloc(sizeof(STRINGLIST));
|
STRINGLIST* strlist = (STRINGLIST*)malloc(sizeof(STRINGLIST));
|
||||||
STRINGLIST* curr = strlist;
|
STRINGLIST* curr = strlist;
|
||||||
|
|
1
util.h
1
util.h
|
@ -28,6 +28,7 @@ int countplaces(int n);
|
||||||
char* itoa(int i);
|
char* itoa(int i);
|
||||||
void* copy(void* v, int size);
|
void* copy(void* v, int size);
|
||||||
|
|
||||||
|
STRINGLIST* onestr(const char* str);
|
||||||
STRINGLIST* initstrlist(const char** strs, int count);
|
STRINGLIST* initstrlist(const char** strs, int count);
|
||||||
void printstrlist(STRINGLIST* strlist, FILE* stream);
|
void printstrlist(STRINGLIST* strlist, FILE* stream);
|
||||||
void freestrlist(STRINGLIST* strlist);
|
void freestrlist(STRINGLIST* strlist);
|
||||||
|
|
Loading…
Reference in New Issue