Add operating system subroutine signatures
This commit is contained in:
parent
0a6149d08f
commit
a1c8c817c8
|
@ -2,6 +2,7 @@
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "compiler-scopes.h"
|
#include "compiler-scopes.h"
|
||||||
|
#include "os.h"
|
||||||
|
|
||||||
typedef enum { local, staticseg, arg, fieldseg } MEMSEGMENT;
|
typedef enum { local, staticseg, arg, fieldseg } MEMSEGMENT;
|
||||||
char* memsegnames[] = { "local", "static", "argument", "this" };
|
char* memsegnames[] = { "local", "static", "argument", "this" };
|
||||||
|
@ -16,7 +17,7 @@ CLASS* getclass(SCOPE* s, const char* name);
|
||||||
SUBROUTDEC* getsubroutdecfromlist(SUBROUTDEC* start, char* name);
|
SUBROUTDEC* getsubroutdecfromlist(SUBROUTDEC* start, char* name);
|
||||||
SUBROUTDEC* getmethod(SCOPE* s, VAR* parent, SUBROUTCALL* call);
|
SUBROUTDEC* getmethod(SCOPE* s, VAR* parent, SUBROUTCALL* call);
|
||||||
SUBROUTDEC* getfunction(SCOPE* s, SUBROUTCALL* call);
|
SUBROUTDEC* getfunction(SCOPE* s, SUBROUTCALL* call);
|
||||||
SUBROUTDEC* getsubroutdecwithparent(SCOPE* s, SUBROUTCALL* call);
|
SUBROUTDEC* getsubroutdecwithparent(SCOPE* s, SUBROUTCALL* call, VAR** varret);
|
||||||
SUBROUTDEC* getsubroutdecwithoutparent(SCOPE* s, SUBROUTCALL* call);
|
SUBROUTDEC* getsubroutdecwithoutparent(SCOPE* s, SUBROUTCALL* call);
|
||||||
SUBROUTDEC* getsubroutdec(SCOPE* s, const char* name);
|
SUBROUTDEC* getsubroutdec(SCOPE* s, const char* name);
|
||||||
|
|
||||||
|
@ -124,7 +125,7 @@ SUBROUTDEC* getmethod(SCOPE* s, VAR* parent, SUBROUTCALL* call) {
|
||||||
CLASS* c = getclass(s, parent->type);
|
CLASS* c = getclass(s, parent->type);
|
||||||
SUBROUTDEC* d = getsubroutdecfromlist(c->subroutdecs, call->name);
|
SUBROUTDEC* d = getsubroutdecfromlist(c->subroutdecs, call->name);
|
||||||
if(d == NULL)
|
if(d == NULL)
|
||||||
notdeclared(call->name, call->debug);
|
return NULL;
|
||||||
if(d->subroutclass != method) {
|
if(d->subroutclass != method) {
|
||||||
eprintf("Calling a function/constructor as if it were a method; file '%s', line %i\n", call->debug->file, call->debug->definedat);
|
eprintf("Calling a function/constructor as if it were a method; file '%s', line %i\n", call->debug->file, call->debug->definedat);
|
||||||
exit(1);
|
exit(1);
|
||||||
|
@ -138,7 +139,7 @@ SUBROUTDEC* getfunction(SCOPE* s, SUBROUTCALL* call) {
|
||||||
notdeclared(call->parentname, call->debug);
|
notdeclared(call->parentname, call->debug);
|
||||||
SUBROUTDEC* d = getsubroutdecfromlist(c->subroutdecs, call->name);
|
SUBROUTDEC* d = getsubroutdecfromlist(c->subroutdecs, call->name);
|
||||||
if(d == NULL)
|
if(d == NULL)
|
||||||
notdeclared(call->name, call->debug);
|
return NULL;
|
||||||
if(d->subroutclass == method) {
|
if(d->subroutclass == method) {
|
||||||
eprintf("Calling a method as if it were a function; file '%s', line %i\n", call->debug->file, call->debug->definedat);
|
eprintf("Calling a method as if it were a function; file '%s', line %i\n", call->debug->file, call->debug->definedat);
|
||||||
exit(1);
|
exit(1);
|
||||||
|
@ -146,26 +147,39 @@ SUBROUTDEC* getfunction(SCOPE* s, SUBROUTCALL* call) {
|
||||||
return d;
|
return d;
|
||||||
}
|
}
|
||||||
|
|
||||||
SUBROUTDEC* getsubroutdecwithparent(SCOPE* s, SUBROUTCALL* call) {
|
SUBROUTDEC* getsubroutdecwithparent(SCOPE* s, SUBROUTCALL* call, VAR** varret) {
|
||||||
VAR* parent = getvar(s, call->parentname);
|
VAR* parent = getvar(s, call->parentname);
|
||||||
if(parent != NULL)
|
if(parent != NULL) {
|
||||||
|
if(parent->primitive) {
|
||||||
|
eprintf("Primitive type does not have subroutines; file '%s', line %i\n", call->debug->file, call->debug->definedat);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
*varret = parent;
|
||||||
return getmethod(s, parent, call);
|
return getmethod(s, parent, call);
|
||||||
else
|
}
|
||||||
|
else
|
||||||
return getfunction(s, call);
|
return getfunction(s, call);
|
||||||
}
|
}
|
||||||
|
|
||||||
SUBROUTDEC* getsubroutdecwithoutparent(SCOPE* s, SUBROUTCALL* call) {
|
SUBROUTDEC* getsubroutdecwithoutparent(SCOPE* s, SUBROUTCALL* call) {
|
||||||
SUBROUTDEC* d = getsubroutdecfromlist(s->currclass->subroutdecs, call->name);
|
SUBROUTDEC* d = getsubroutdecfromlist(s->currclass->subroutdecs, call->name);
|
||||||
if(d == NULL)
|
|
||||||
notdeclared(call->name, call->debug);
|
|
||||||
return d;
|
return d;
|
||||||
}
|
}
|
||||||
|
|
||||||
SUBROUTDEC* getsubroutdecfromcall(SCOPE* s, SUBROUTCALL* call) {
|
SUBROUTDEC* getsubroutdecfromcall(SCOPE* s, SUBROUTCALL* call, VAR** varret) {
|
||||||
if(call->parentname != NULL)
|
SUBROUTDEC* d;
|
||||||
return getsubroutdecwithparent(s, call);
|
*varret = NULL;
|
||||||
else
|
if(call->parentname != NULL) {
|
||||||
return getsubroutdecwithoutparent(s, call);
|
d = getossubroutdec(call);
|
||||||
|
if(d == NULL)
|
||||||
|
d = getsubroutdecwithparent(s, call, varret);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
d = getsubroutdecwithoutparent(s, call);
|
||||||
|
}
|
||||||
|
if(d == NULL)
|
||||||
|
notdeclared(call->name, call->debug);
|
||||||
|
return d;
|
||||||
}
|
}
|
||||||
|
|
||||||
SUBROUTDEC* getsubroutdec(SCOPE* s, const char* name) {
|
SUBROUTDEC* getsubroutdec(SCOPE* s, const char* name) {
|
||||||
|
@ -234,7 +248,7 @@ void addfield(SCOPE* s, CLASSVARDEC* v) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void addclassvardec(SCOPE* s, CLASSVARDEC* v) {
|
void addclassvardec(SCOPE* s, CLASSVARDEC* v) {
|
||||||
if(v->type == staticseg)
|
if(v->type == stat)
|
||||||
addstaticvar(s, v);
|
addstaticvar(s, v);
|
||||||
else
|
else
|
||||||
addfield(s, v);
|
addfield(s, v);
|
||||||
|
|
|
@ -43,7 +43,7 @@ void addparameters(SCOPE* s, PARAMETER* params);
|
||||||
SCOPE* mkscope(SCOPE* prev);
|
SCOPE* mkscope(SCOPE* prev);
|
||||||
|
|
||||||
// Single type getters
|
// Single type getters
|
||||||
SUBROUTDEC* getsubroutdecfromcall(SCOPE* s, SUBROUTCALL* call);
|
SUBROUTDEC* getsubroutdecfromcall(SCOPE* s, SUBROUTCALL* call, VAR** varret);
|
||||||
CLASS* getclass(SCOPE* s, const char* name);
|
CLASS* getclass(SCOPE* s, const char* name);
|
||||||
|
|
||||||
// Generic getters
|
// Generic getters
|
||||||
|
|
|
@ -108,11 +108,18 @@ LINEBLOCK* pushunaryopterm(SCOPE* s, TERM* t) {
|
||||||
return blk;
|
return blk;
|
||||||
}
|
}
|
||||||
|
|
||||||
LINEBLOCK* opvar(SCOPE* s, char* op, const char* name) {
|
LINEBLOCK* opvarraw(SCOPE* s, char* op, VAR* v) {
|
||||||
VAR* v = getvar(s, name);
|
|
||||||
char* tokens[] = { op, v->memsegment, itoa(v->index) };
|
char* tokens[] = { op, v->memsegment, itoa(v->index) };
|
||||||
return mklnblk(mksimpleln(tokens, strcount(tokens)));
|
return mklnblk(mksimpleln(tokens, strcount(tokens)));
|
||||||
|
}
|
||||||
|
|
||||||
|
LINEBLOCK* opvar(SCOPE* s, char* op, const char* name) {
|
||||||
|
VAR* v = getvar(s, name);
|
||||||
|
return opvarraw(s, op, v);
|
||||||
|
}
|
||||||
|
|
||||||
|
LINEBLOCK* pushvarraw(SCOPE*s, VAR* v) {
|
||||||
|
return opvarraw(s, "push", v);
|
||||||
}
|
}
|
||||||
|
|
||||||
LINEBLOCK* pushvar(SCOPE* s, const char* name) {
|
LINEBLOCK* pushvar(SCOPE* s, const char* name) {
|
||||||
|
@ -185,64 +192,39 @@ LINEBLOCK* compileexplist(SCOPE* s, EXPRESSIONLIST* explist) {
|
||||||
return head;
|
return head;
|
||||||
}
|
}
|
||||||
|
|
||||||
LINEBLOCK* compilecallln(SCOPE* s, SUBROUTCALL* call) {
|
LINEBLOCK* compilecallln(SCOPE* s, SUBROUTDEC* d, SUBROUTCALL* call) {
|
||||||
LINE* ln = mkline(3);
|
LINE* ln = mkline(3);
|
||||||
|
|
||||||
addtoken(ln, ezheapstr("call"));
|
addtoken(ln, ezheapstr("call"));
|
||||||
|
|
||||||
if(call->parentname != NULL)
|
addtoken(ln, dotlabel(d->class->name, call->name));
|
||||||
addtoken(ln, dotlabel(call->parentname, call->name));
|
|
||||||
else
|
|
||||||
addtoken(ln, dotlabel(s->currclass->name, call->name));
|
|
||||||
|
|
||||||
addtoken(ln, itoa(countexpressions(call->parameters)));
|
int count = countexpressions(call->parameters);
|
||||||
|
if(d->subroutclass == method)
|
||||||
|
count++;
|
||||||
|
addtoken(ln, itoa(count));
|
||||||
|
|
||||||
return mklnblk(ln);
|
return mklnblk(ln);
|
||||||
}
|
}
|
||||||
|
|
||||||
// temporary ignore list for OS functions
|
|
||||||
char* ignoresubroutdecs[] = {
|
|
||||||
"printInt", "void", "peek", "int", "poke", "void", "deAlloc", "void", "setColor", "void", "drawRectangle", "void",
|
|
||||||
"wait", "void", "keyPressed", "char"
|
|
||||||
};
|
|
||||||
int ignorecount = sizeof(ignoresubroutdecs) / sizeof(char*);
|
|
||||||
|
|
||||||
SUBROUTCLASS ignoreclasses[] = {
|
|
||||||
function, function, function, function, function, function, function, function
|
|
||||||
};
|
|
||||||
|
|
||||||
LINEBLOCK* compilesubroutcall(SCOPE* s, SUBROUTCALL* call) {
|
LINEBLOCK* compilesubroutcall(SCOPE* s, SUBROUTCALL* call) {
|
||||||
LINEBLOCK* blk = compilecallln(s, call);
|
VAR* v;
|
||||||
|
SUBROUTDEC* d = getsubroutdecfromcall(s, call, &v);
|
||||||
|
LINEBLOCK* blk = compilecallln(s, d, call);
|
||||||
|
|
||||||
if(call->parameters != NULL)
|
if(call->parameters != NULL)
|
||||||
blk = mergelnblks(compileexplist(s, call->parameters), blk);
|
blk = mergelnblks(compileexplist(s, call->parameters), blk);
|
||||||
|
|
||||||
// void functions always return 0
|
if(d->subroutclass == method) {
|
||||||
// therefore must be thrown away
|
|
||||||
|
|
||||||
// gambiarra
|
|
||||||
SUBROUTCLASS class;
|
|
||||||
char* type = NULL;
|
|
||||||
for(int i = 0; i < ignorecount; i += 2) {
|
|
||||||
if(!strcmp(call->name, ignoresubroutdecs[i])) {
|
|
||||||
type = ignoresubroutdecs[i+1];
|
|
||||||
class = ignoreclasses[i];
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(type == NULL) {
|
|
||||||
SUBROUTDEC* dec = getsubroutdecfromcall(s, call);
|
|
||||||
type = dec->type;
|
|
||||||
class = dec->subroutclass;
|
|
||||||
}
|
|
||||||
if(class == method) {
|
|
||||||
// could be more efficient since getsubroutdecfromcall() gets the parent already
|
|
||||||
if(call->parentname == NULL)
|
if(call->parentname == NULL)
|
||||||
blk = mergelnblks(pushthis(), blk);
|
blk = mergelnblks(pushthis(), blk);
|
||||||
else
|
else
|
||||||
blk = mergelnblks(pushvar(s, call->parentname), blk);
|
blk = mergelnblks(pushvarraw(s, v), blk);
|
||||||
}
|
}
|
||||||
if(!strcmp(type, "void")) {
|
|
||||||
|
// void functions always return 0
|
||||||
|
// therefore must be thrown away
|
||||||
|
if(!strcmp(d->type, "void")) {
|
||||||
char* tokens[] = { "pop", "temp", "0" };
|
char* tokens[] = { "pop", "temp", "0" };
|
||||||
appendln(blk, mksimpleln(tokens, sizeof(tokens) / sizeof(char*)));
|
appendln(blk, mksimpleln(tokens, sizeof(tokens) / sizeof(char*)));
|
||||||
}
|
}
|
||||||
|
@ -418,13 +400,13 @@ LINEBLOCK* compileconstructor(COMPILER* c, SCOPE* s, CLASS* cl, SUBROUTDEC* con)
|
||||||
LINE* label = mksubdeclabel(cl, con);
|
LINE* label = mksubdeclabel(cl, con);
|
||||||
LINEBLOCK* blk = mklnblk(label);
|
LINEBLOCK* blk = mklnblk(label);
|
||||||
|
|
||||||
char* size[] = { "push", itoa(getobjsize(cl)) };
|
char* size[] = { "push", "constant", itoa(getobjsize(cl)) };
|
||||||
char* memalloc[] = { "call", "Memory.alloc", "1" };
|
char* memalloc[] = { "call", "Memory.alloc", "1" };
|
||||||
char* poppointer[] = { "pop", "pointer", "0" };
|
char* poppointer[] = { "pop", "pointer", "0" };
|
||||||
appendln(blk, mksimpleln(size, strcount(size)));
|
appendln(blk, mksimpleln(size, strcount(size)));
|
||||||
appendln(blk, mksimpleln(memalloc, strcount(memalloc)));
|
appendln(blk, mksimpleln(memalloc, strcount(memalloc)));
|
||||||
appendln(blk, mksimpleln(poppointer, strcount(poppointer)));
|
appendln(blk, mksimpleln(poppointer, strcount(poppointer)));
|
||||||
free(size[1]);
|
free(size[2]);
|
||||||
|
|
||||||
if(con->body != NULL)
|
if(con->body != NULL)
|
||||||
return mergelnblks(blk, compilefunbody(c, s, cl, con->body));
|
return mergelnblks(blk, compilefunbody(c, s, cl, con->body));
|
||||||
|
@ -436,7 +418,7 @@ LINEBLOCK* compilemethod(COMPILER* c, SCOPE* s, CLASS* cl, SUBROUTDEC* m) {
|
||||||
LINE* label = mksubdeclabel(cl, m);
|
LINE* label = mksubdeclabel(cl, m);
|
||||||
LINEBLOCK* blk = mklnblk(label);
|
LINEBLOCK* blk = mklnblk(label);
|
||||||
|
|
||||||
char* pusharg0[] = { "push", "argument" "0" };
|
char* pusharg0[] = { "push", "argument", "0" };
|
||||||
char* poppointer[] = { "pop", "pointer", "0" };
|
char* poppointer[] = { "pop", "pointer", "0" };
|
||||||
appendln(blk, mksimpleln(pusharg0, strcount(pusharg0)));
|
appendln(blk, mksimpleln(pusharg0, strcount(pusharg0)));
|
||||||
appendln(blk, mksimpleln(poppointer, strcount(poppointer)));
|
appendln(blk, mksimpleln(poppointer, strcount(poppointer)));
|
||||||
|
|
3
main.c
3
main.c
|
@ -7,6 +7,7 @@
|
||||||
#include "parser.h"
|
#include "parser.h"
|
||||||
#include "compiler.h"
|
#include "compiler.h"
|
||||||
#include "io.h"
|
#include "io.h"
|
||||||
|
#include "os.h"
|
||||||
|
|
||||||
typedef struct unit {
|
typedef struct unit {
|
||||||
FILELIST* file;
|
FILELIST* file;
|
||||||
|
@ -119,6 +120,7 @@ int main(int argc, char* argv[]) {
|
||||||
currunit = currunit->next;
|
currunit = currunit->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
populateos();
|
||||||
actonunits(head, compileunit);
|
actonunits(head, compileunit);
|
||||||
|
|
||||||
currunit = head;
|
currunit = head;
|
||||||
|
@ -133,5 +135,6 @@ int main(int argc, char* argv[]) {
|
||||||
currunit = currunit->next;
|
currunit = currunit->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
freeos();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,159 @@
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include "os.h"
|
||||||
|
#include "util.h"
|
||||||
|
|
||||||
|
#define MATH_COUNT 5
|
||||||
|
SUBROUTDEC* math[MATH_COUNT];
|
||||||
|
#define STRING_COUNT 12
|
||||||
|
SUBROUTDEC* stringclass[STRING_COUNT];
|
||||||
|
#define ARRAY_COUNT 2
|
||||||
|
SUBROUTDEC* array[ARRAY_COUNT];
|
||||||
|
#define OUTPUT_COUNT 6
|
||||||
|
SUBROUTDEC* output[OUTPUT_COUNT];
|
||||||
|
#define SCREEN_COUNT 6
|
||||||
|
SUBROUTDEC* screen[SCREEN_COUNT];
|
||||||
|
#define KEYBOARD_COUNT 4
|
||||||
|
SUBROUTDEC* keyboard[KEYBOARD_COUNT];
|
||||||
|
#define MEMORY_COUNT 4
|
||||||
|
SUBROUTDEC* memory[MEMORY_COUNT];
|
||||||
|
#define SYS_COUNT 3
|
||||||
|
SUBROUTDEC* sys[SYS_COUNT];
|
||||||
|
|
||||||
|
CLASS* mkclass(const char* name) {
|
||||||
|
CLASS* class = (CLASS*)malloc(sizeof(CLASS));
|
||||||
|
class->name = ezheapstr(name);
|
||||||
|
return class;
|
||||||
|
}
|
||||||
|
|
||||||
|
SUBROUTDEC* mkdec(const char* class, SUBROUTCLASS subroutclass, char* type, const char* name) {
|
||||||
|
SUBROUTDEC* dec = (SUBROUTDEC*)malloc(sizeof(SUBROUTDEC));
|
||||||
|
dec->class = mkclass(class);
|
||||||
|
dec->subroutclass = subroutclass;
|
||||||
|
dec->type = type;
|
||||||
|
dec->name = ezheapstr(name);
|
||||||
|
return dec;
|
||||||
|
}
|
||||||
|
|
||||||
|
void populatemath() {
|
||||||
|
math[0] = mkdec("Math", function, "int", "multiply");
|
||||||
|
math[1] = mkdec("Math", function, "int", "divide");
|
||||||
|
math[2] = mkdec("Math", function, "int", "min");
|
||||||
|
math[3] = mkdec("Math", function, "int", "max");
|
||||||
|
math[4] = mkdec("Math", function, "int", "sqrt");
|
||||||
|
}
|
||||||
|
|
||||||
|
void populatestringclass() {
|
||||||
|
stringclass[0] = mkdec("String", constructor, "String", "new");
|
||||||
|
stringclass[1] = mkdec("String", method, "int", "dispose");
|
||||||
|
stringclass[2] = mkdec("String", method, "int", "length");
|
||||||
|
stringclass[3] = mkdec("String", method, "char", "charAt");
|
||||||
|
stringclass[4] = mkdec("String", method, "void", "setCharAt");
|
||||||
|
stringclass[5] = mkdec("String", method, "String", "appendChar");
|
||||||
|
stringclass[6] = mkdec("String", method, "void", "eraseLastChar");
|
||||||
|
stringclass[7] = mkdec("String", method, "int", "intValue");
|
||||||
|
stringclass[8] = mkdec("String", method, "void", "setInt");
|
||||||
|
stringclass[9] = mkdec("String", function, "char", "backSpace");
|
||||||
|
stringclass[10] = mkdec("String", function, "char", "doubleQuote");
|
||||||
|
stringclass[11] = mkdec("String", function, "char", "newLine");
|
||||||
|
}
|
||||||
|
|
||||||
|
void populatearray() {
|
||||||
|
array[0] = mkdec("Array", function, "Array", "new");
|
||||||
|
array[1] = mkdec("Array", method, "void", "dispose");
|
||||||
|
}
|
||||||
|
|
||||||
|
void populateoutput() {
|
||||||
|
output[0] = mkdec("Output", function, "void", "moveCursor");
|
||||||
|
output[1] = mkdec("Output", function, "void", "printChar");
|
||||||
|
output[2] = mkdec("Output", function, "void", "printString");
|
||||||
|
output[3] = mkdec("Output", function, "void", "printInt");
|
||||||
|
output[4] = mkdec("Output", function, "void", "printLn");
|
||||||
|
output[5] = mkdec("Output", function, "void", "backSpace");
|
||||||
|
}
|
||||||
|
|
||||||
|
void populatescreen() {
|
||||||
|
screen[0] = mkdec("Screen", function, "void", "clearScreen");
|
||||||
|
screen[1] = mkdec("Screen", function, "void", "setColor");
|
||||||
|
screen[2] = mkdec("Screen", function, "void", "drawPixel");
|
||||||
|
screen[3] = mkdec("Screen", function, "void", "drawLine");
|
||||||
|
screen[4] = mkdec("Screen", function, "void", "drawRectangle");
|
||||||
|
screen[5] = mkdec("Screen", function, "void", "drawCircle");
|
||||||
|
}
|
||||||
|
|
||||||
|
void populatekeyboard() {
|
||||||
|
keyboard[0] = mkdec("Keyboard", function, "char", "keyPressed");
|
||||||
|
keyboard[1] = mkdec("Keyboard", function, "char", "readChar");
|
||||||
|
keyboard[2] = mkdec("Keyboard", function, "String", "readLine");
|
||||||
|
keyboard[3] = mkdec("Keyboard", function, "int", "readInt");
|
||||||
|
}
|
||||||
|
|
||||||
|
void populatememory() {
|
||||||
|
memory[0] = mkdec("Memory", function, "int", "peek");
|
||||||
|
memory[1] = mkdec("Memory", function, "void", "poke");
|
||||||
|
memory[2] = mkdec("Memory", function, "Array", "alloc");
|
||||||
|
memory[3] = mkdec("Memory", function, "void", "deAlloc");
|
||||||
|
}
|
||||||
|
|
||||||
|
void populatesys() {
|
||||||
|
sys[0] = mkdec("Sys", function, "void", "halt");
|
||||||
|
sys[1] = mkdec("Sys", function, "void", "error");
|
||||||
|
sys[2] = mkdec("Sys", function, "void", "wait");
|
||||||
|
}
|
||||||
|
|
||||||
|
void populateos() {
|
||||||
|
populatemath();
|
||||||
|
populatestringclass();
|
||||||
|
populatearray();
|
||||||
|
populateoutput();
|
||||||
|
populatescreen();
|
||||||
|
populatekeyboard();
|
||||||
|
populatememory();
|
||||||
|
populatesys();
|
||||||
|
}
|
||||||
|
|
||||||
|
void freedecs(SUBROUTDEC** array, int size) {
|
||||||
|
for(int i = 0; i < size; i++) {
|
||||||
|
free(array[i]->class->name);
|
||||||
|
free(array[i]->class);
|
||||||
|
free(array[i]->name);
|
||||||
|
free(array[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void freeos() {
|
||||||
|
freedecs(math, MATH_COUNT);
|
||||||
|
freedecs(stringclass, STRING_COUNT);
|
||||||
|
freedecs(array, ARRAY_COUNT);
|
||||||
|
freedecs(output, OUTPUT_COUNT);
|
||||||
|
freedecs(screen, SCREEN_COUNT);
|
||||||
|
freedecs(keyboard, KEYBOARD_COUNT);
|
||||||
|
freedecs(memory, MEMORY_COUNT);
|
||||||
|
freedecs(sys, SYS_COUNT);
|
||||||
|
}
|
||||||
|
|
||||||
|
SUBROUTDEC* getdec(SUBROUTDEC** array, int size, const char* name) {
|
||||||
|
for(int i = 0; i < size; i++)
|
||||||
|
if(!strcmp(array[i]->name, name))
|
||||||
|
return array[i];
|
||||||
|
}
|
||||||
|
|
||||||
|
SUBROUTDEC* getossubroutdec(SUBROUTCALL* call) {
|
||||||
|
if(!strcmp(call->parentname, "Math"))
|
||||||
|
return getdec(math, MATH_COUNT, call->name);
|
||||||
|
if(!strcmp(call->parentname, "String"))
|
||||||
|
return getdec(stringclass, STRING_COUNT, call->name);
|
||||||
|
if(!strcmp(call->parentname, "Array"))
|
||||||
|
return getdec(array, ARRAY_COUNT, call->name);
|
||||||
|
if(!strcmp(call->parentname, "Output"))
|
||||||
|
return getdec(output, OUTPUT_COUNT, call->name);
|
||||||
|
if(!strcmp(call->parentname, "Screen"))
|
||||||
|
return getdec(screen, SCREEN_COUNT, call->name);
|
||||||
|
if(!strcmp(call->parentname, "Keyboard"))
|
||||||
|
return getdec(keyboard, KEYBOARD_COUNT, call->name);
|
||||||
|
if(!strcmp(call->parentname, "Memory"))
|
||||||
|
return getdec(memory, MEMORY_COUNT, call->name);
|
||||||
|
if(!strcmp(call->parentname, "Sys"))
|
||||||
|
return getdec(sys, SYS_COUNT, call->name);
|
||||||
|
return NULL;
|
||||||
|
}
|
|
@ -0,0 +1,9 @@
|
||||||
|
#ifndef OS_H
|
||||||
|
#define OS_H
|
||||||
|
#include "parser-tree.h"
|
||||||
|
|
||||||
|
SUBROUTDEC* getossubroutdec(SUBROUTCALL* call);
|
||||||
|
void populateos();
|
||||||
|
void freeos();
|
||||||
|
|
||||||
|
#endif
|
|
@ -9,8 +9,8 @@ CLASSVARTYPE parseclassvartype(PARSER* p);
|
||||||
CLASSVARDEC* parseclassvardec(PARSER* p);
|
CLASSVARDEC* parseclassvardec(PARSER* p);
|
||||||
CLASSVARDEC* parseclassvardecs(PARSER* p);
|
CLASSVARDEC* parseclassvardecs(PARSER* p);
|
||||||
SUBROUTCLASS parsesubroutclass(PARSER* p);
|
SUBROUTCLASS parsesubroutclass(PARSER* p);
|
||||||
SUBROUTDEC* parsesubroutdec(PARSER* p);
|
SUBROUTDEC* parsesubroutdec(PARSER* p, CLASS* c);
|
||||||
SUBROUTDEC* parsesubroutdecs(PARSER* p);
|
SUBROUTDEC* parsesubroutdecs(PARSER* p, CLASS* c);
|
||||||
PARAMETER* parseparameter(PARSER* p);
|
PARAMETER* parseparameter(PARSER* p);
|
||||||
PARAMETER* parseparameters(PARSER* p);
|
PARAMETER* parseparameters(PARSER* p);
|
||||||
SUBROUTBODY* parsesubroutbody(PARSER* p);
|
SUBROUTBODY* parsesubroutbody(PARSER* p);
|
||||||
|
@ -40,7 +40,7 @@ CLASS* parseclass(PARSER* p) {
|
||||||
|
|
||||||
class->vardecs = parseclassvardecs(p);
|
class->vardecs = parseclassvardecs(p);
|
||||||
|
|
||||||
class->subroutdecs = parsesubroutdecs(p);
|
class->subroutdecs = parsesubroutdecs(p, class);
|
||||||
|
|
||||||
checkcontent(p, "}");
|
checkcontent(p, "}");
|
||||||
|
|
||||||
|
@ -94,7 +94,7 @@ SUBROUTCLASS parsesubroutclass(PARSER* p) {
|
||||||
return parsepossibilities(p, &subroutclasses);
|
return parsepossibilities(p, &subroutclasses);
|
||||||
}
|
}
|
||||||
|
|
||||||
SUBROUTDEC* parsesubroutdec(PARSER* p) {
|
SUBROUTDEC* parsesubroutdec(PARSER* p, CLASS* c) {
|
||||||
SUBROUTCLASS subroutclass = parsesubroutclass(p);
|
SUBROUTCLASS subroutclass = parsesubroutclass(p);
|
||||||
if(subroutclass == -1)
|
if(subroutclass == -1)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -122,14 +122,16 @@ SUBROUTDEC* parsesubroutdec(PARSER* p) {
|
||||||
subroutdec->body = parsesubroutbody(p);
|
subroutdec->body = parsesubroutbody(p);
|
||||||
checkcontent(p, "}");
|
checkcontent(p, "}");
|
||||||
|
|
||||||
|
subroutdec->class = c;
|
||||||
|
|
||||||
return subroutdec;
|
return subroutdec;
|
||||||
}
|
}
|
||||||
|
|
||||||
SUBROUTDEC* parsesubroutdecs(PARSER* p) {
|
SUBROUTDEC* parsesubroutdecs(PARSER* p, CLASS* c) {
|
||||||
SUBROUTDEC* head = parsesubroutdec(p);
|
SUBROUTDEC* head = parsesubroutdec(p, c);
|
||||||
SUBROUTDEC* curr = head;
|
SUBROUTDEC* curr = head;
|
||||||
SUBROUTDEC* nexts;
|
SUBROUTDEC* nexts;
|
||||||
while(nexts = parsesubroutdec(p), nexts != NULL) {
|
while(nexts = parsesubroutdec(p, c), nexts != NULL) {
|
||||||
curr->next = nexts;
|
curr->next = nexts;
|
||||||
curr = nexts;
|
curr = nexts;
|
||||||
}
|
}
|
||||||
|
|
|
@ -49,6 +49,7 @@ typedef enum {
|
||||||
|
|
||||||
typedef struct subroutdec {
|
typedef struct subroutdec {
|
||||||
SUBROUTCLASS subroutclass;
|
SUBROUTCLASS subroutclass;
|
||||||
|
CLASS* class;
|
||||||
char* type;
|
char* type;
|
||||||
char* name;
|
char* name;
|
||||||
struct parameter* parameters;
|
struct parameter* parameters;
|
||||||
|
|
Loading…
Reference in New Issue