|
@@ -208,158 +208,104 @@ static DataType cCallFunction(const char* name) {
|
|
return found->returnType;
|
|
return found->returnType;
|
|
}
|
|
}
|
|
|
|
|
|
-static void cAddOffset(int offset) {
|
|
|
|
- if(offset > 0) {
|
|
|
|
- cAddOperation(OP_PUSH_INT);
|
|
|
|
- cAddInt(offset);
|
|
|
|
- cAddOperation(OP_ADD_INT);
|
|
|
|
|
|
+static void cWalkStruct(Variable* v) {
|
|
|
|
+ int pointers;
|
|
|
|
+ if(cConsumeTokenIf(T_ARROW)) {
|
|
|
|
+ pointers = 1;
|
|
|
|
+ cAddOperation(OP_REFERENCE);
|
|
|
|
+ } else if(cConsumeTokenIf(T_POINT)) {
|
|
|
|
+ pointers = 0;
|
|
|
|
+ } else {
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+ Struct* st = dtGetStruct(&structs, v->type);
|
|
|
|
+ if(st == NULL || v->type.pointers != pointers) {
|
|
|
|
+ DataType w = v->type;
|
|
|
|
+ w.pointers = pointers;
|
|
|
|
+ cError("%s is not %s but %s", v->name, cGetName(w), cGetName(v->type));
|
|
|
|
+ }
|
|
|
|
+ cConsumeToken(T_LITERAL);
|
|
|
|
+ const char* name = cReadString();
|
|
|
|
+ Variable inner;
|
|
|
|
+ if(vSearchStruct(&inner, &structs, st, name)) {
|
|
|
|
+ cError("%s has no member %s", v->name, name);
|
|
}
|
|
}
|
|
|
|
+ v->type = inner.type;
|
|
|
|
+ cAddOperation(OP_PUSH_INT);
|
|
|
|
+ cAddInt(inner.address);
|
|
|
|
+ cAddOperation(OP_ADD_INT);
|
|
}
|
|
}
|
|
|
|
|
|
-static DataType cLoadRef(Variable* v, Operation op, DataType dt, int offset) {
|
|
|
|
- cAddOperation(OP_LOAD_INT);
|
|
|
|
|
|
+static void cReference(Variable* v, int dimension) {
|
|
|
|
+ cAddOperation(OP_DEREFERENCE_VAR);
|
|
cAddInt(v->address);
|
|
cAddInt(v->address);
|
|
- cAddOffset(offset);
|
|
|
|
- cAddOperation(op);
|
|
|
|
- return dt;
|
|
|
|
|
|
+ while(dimension > 0) {
|
|
|
|
+ if(!dtIsPointer(v->type)) {
|
|
|
|
+ cError("too many *");
|
|
|
|
+ }
|
|
|
|
+ v->type = dtReference(v->type);
|
|
|
|
+ dimension--;
|
|
|
|
+ cAddOperation(OP_REFERENCE);
|
|
|
|
+ }
|
|
|
|
+ cWalkStruct(v);
|
|
}
|
|
}
|
|
|
|
|
|
-static DataType cAddVariable(Operation op, Variable* v) {
|
|
|
|
- cAddOperation(op);
|
|
|
|
- cAddInt(v->address);
|
|
|
|
- return v->type;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-static DataType cLoadVariable(Variable* v, Variable* sv) {
|
|
|
|
- DataType type = v->type;
|
|
|
|
- int offset = 0;
|
|
|
|
- if(dtIsStruct(type) && sv->type.type != DT_VOID) {
|
|
|
|
- sv->address += v->address;
|
|
|
|
- return cLoadVariable(sv, sv);
|
|
|
|
- } else if(dtIsStructRef(type)) {
|
|
|
|
- type = dtToReference(sv->type);
|
|
|
|
- offset = sv->address;
|
|
|
|
- }
|
|
|
|
- if(dtCompare(type, dtToReference(dtInt()))) {
|
|
|
|
- return cLoadRef(v, OP_REF_LOAD_INT, dtInt(), offset);
|
|
|
|
- } else if(dtCompare(type, dtToReference(dtFloat()))) {
|
|
|
|
- return cLoadRef(v, OP_REF_LOAD_FLOAT, dtFloat(), offset);
|
|
|
|
- } else if(dtCompare(type, dtToReference(dtBool()))) {
|
|
|
|
- return cLoadRef(v, OP_REF_LOAD_BOOL, dtBool(), offset);
|
|
|
|
- }
|
|
|
|
|
|
+static void cLoadRef(Variable* v) {
|
|
switch(dtAsInt(v->type)) {
|
|
switch(dtAsInt(v->type)) {
|
|
- case DT_INT: return cAddVariable(OP_LOAD_INT, v);
|
|
|
|
- case DT_BOOL: return cAddVariable(OP_LOAD_BOOL, v);
|
|
|
|
- case DT_FLOAT: return cAddVariable(OP_LOAD_FLOAT, v);
|
|
|
|
|
|
+ case DT_INT: cAddOperation(OP_REF_LOAD_INT); break;
|
|
|
|
+ case DT_BOOL: cAddOperation(OP_REF_LOAD_BOOL); break;
|
|
|
|
+ case DT_FLOAT: cAddOperation(OP_REF_LOAD_FLOAT); break;
|
|
case DT_STRUCT:
|
|
case DT_STRUCT:
|
|
{
|
|
{
|
|
Struct* st = dtGetStruct(&structs, v->type);
|
|
Struct* st = dtGetStruct(&structs, v->type);
|
|
if(st == NULL) {
|
|
if(st == NULL) {
|
|
cError("compiler struct error");
|
|
cError("compiler struct error");
|
|
}
|
|
}
|
|
- int address = v->address;
|
|
|
|
- for(int i = 0; i < st->amount; i++) {
|
|
|
|
- Variable v = {st->vars[i].name, st->vars[i].type, address};
|
|
|
|
- cLoadVariable(&v, sv);
|
|
|
|
- address += dtGetSize(v.type, &structs);
|
|
|
|
- }
|
|
|
|
- return v->type;
|
|
|
|
|
|
+ cAddOperation(OP_REF_LOAD);
|
|
|
|
+ cAddInt(dtGetSize(v->type, &structs));
|
|
|
|
+ break;
|
|
}
|
|
}
|
|
default:
|
|
default:
|
|
- cError("cannot load type %s", cGetName(v->type));
|
|
|
|
- return dtVoid();
|
|
|
|
- }
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-static bool cStoreRef(Variable* v, Variable* sv, DataType should, DataType dt,
|
|
|
|
- Operation op) {
|
|
|
|
- DataType type = v->type;
|
|
|
|
- int offset = 0;
|
|
|
|
- if(dtIsStructRef(type)) {
|
|
|
|
- type = dtToReference(sv->type);
|
|
|
|
- offset = sv->address;
|
|
|
|
- }
|
|
|
|
- if(dtCompare(type, dtToReference(should)) && dtCompare(dt, should)) {
|
|
|
|
- cAddOperation(OP_LOAD_INT);
|
|
|
|
- cAddInt(v->address);
|
|
|
|
- cAddOffset(offset);
|
|
|
|
- cAddOperation(op);
|
|
|
|
- return true;
|
|
|
|
|
|
+ if(dtIsPointer(v->type)) {
|
|
|
|
+ cAddOperation(OP_REF_LOAD_INT);
|
|
|
|
+ } else {
|
|
|
|
+ cError("cannot load type %s", cGetName(v->type));
|
|
|
|
+ }
|
|
}
|
|
}
|
|
- return false;
|
|
|
|
}
|
|
}
|
|
|
|
|
|
static void cStore(Variable* v, DataType dt, const char* name) {
|
|
static void cStore(Variable* v, DataType dt, const char* name) {
|
|
if(!dtCompare(v->type, dt)) {
|
|
if(!dtCompare(v->type, dt)) {
|
|
cInvalidOperation(v->type, dt, name);
|
|
cInvalidOperation(v->type, dt, name);
|
|
- } else if(v->type.reference) {
|
|
|
|
- cAddOperation(OP_STORE_INT);
|
|
|
|
- cAddInt(v->address);
|
|
|
|
- return;
|
|
|
|
}
|
|
}
|
|
switch(dtAsInt(v->type)) {
|
|
switch(dtAsInt(v->type)) {
|
|
case DT_INT: cAddOperation(OP_STORE_INT); break;
|
|
case DT_INT: cAddOperation(OP_STORE_INT); break;
|
|
case DT_BOOL: cAddOperation(OP_STORE_BOOL); break;
|
|
case DT_BOOL: cAddOperation(OP_STORE_BOOL); break;
|
|
case DT_FLOAT: cAddOperation(OP_STORE_FLOAT); break;
|
|
case DT_FLOAT: cAddOperation(OP_STORE_FLOAT); break;
|
|
default:
|
|
default:
|
|
- if(dtIsArray(v->type)) {
|
|
|
|
|
|
+ if(dtIsPointer(v->type)) {
|
|
cAddOperation(OP_STORE_ARRAY);
|
|
cAddOperation(OP_STORE_ARRAY);
|
|
} else {
|
|
} else {
|
|
cError("cannot store type %s", cGetName(v->type));
|
|
cError("cannot store type %s", cGetName(v->type));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
- cAddInt(v->address);
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-static void cStoreVariable(Variable* v, Variable* sv, DataType dt,
|
|
|
|
- const char* name) {
|
|
|
|
- if(cStoreRef(v, sv, dtInt(), dt, OP_REF_STORE_INT) ||
|
|
|
|
- cStoreRef(v, sv, dtFloat(), dt, OP_REF_STORE_FLOAT) ||
|
|
|
|
- cStoreRef(v, sv, dtBool(), dt, OP_REF_STORE_BOOL)) {
|
|
|
|
- return;
|
|
|
|
- }
|
|
|
|
- if(dtIsStruct(v->type) && sv->type.type != DT_VOID) {
|
|
|
|
- sv->address += v->address;
|
|
|
|
- cStore(sv, dt, name);
|
|
|
|
- } else {
|
|
|
|
- cStore(v, dt, name);
|
|
|
|
- }
|
|
|
|
}
|
|
}
|
|
|
|
|
|
static DataType cPostChange(Variable* v, int change, const char* name) {
|
|
static DataType cPostChange(Variable* v, int change, const char* name) {
|
|
if(!dtCompare(v->type, dtInt())) {
|
|
if(!dtCompare(v->type, dtInt())) {
|
|
cError("%s needs an int", name);
|
|
cError("%s needs an int", name);
|
|
}
|
|
}
|
|
- cAddOperation(OP_LOAD_INT);
|
|
|
|
- cAddInt(v->address);
|
|
|
|
- cAddOperation(OP_LOAD_INT);
|
|
|
|
- cAddInt(v->address);
|
|
|
|
|
|
+ cAddOperation(OP_REF_LOAD_INT);
|
|
|
|
+ cReference(v, 0);
|
|
|
|
+ cAddOperation(OP_DUPLICATE_REFERENCE);
|
|
|
|
+ cAddOperation(OP_REF_LOAD_INT);
|
|
cAddOperation(OP_PUSH_INT);
|
|
cAddOperation(OP_PUSH_INT);
|
|
cAddInt(change);
|
|
cAddInt(change);
|
|
cAddOperation(OP_ADD_INT);
|
|
cAddOperation(OP_ADD_INT);
|
|
cAddOperation(OP_STORE_INT);
|
|
cAddOperation(OP_STORE_INT);
|
|
- cAddInt(v->address);
|
|
|
|
return dtInt();
|
|
return dtInt();
|
|
}
|
|
}
|
|
|
|
|
|
-static void cWalkStruct(Variable* v, Variable* sv) {
|
|
|
|
- sv->address = 0;
|
|
|
|
- sv->name = "";
|
|
|
|
- sv->type = dtVoid();
|
|
|
|
- if(!cConsumeTokenIf(T_POINT)) {
|
|
|
|
- return;
|
|
|
|
- }
|
|
|
|
- Struct* st = dtGetStruct(&structs, v->type);
|
|
|
|
- if(st == NULL) {
|
|
|
|
- cError("%s is not a struct but %s", v->name, cGetName(v->type));
|
|
|
|
- }
|
|
|
|
- cConsumeToken(T_LITERAL);
|
|
|
|
- const char* name = cReadString();
|
|
|
|
- if(vSearchStruct(sv, &structs, st, name)) {
|
|
|
|
- cError("%s has no member %s", v->name, name);
|
|
|
|
- }
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
static DataType cLiteral() {
|
|
static DataType cLiteral() {
|
|
const char* literal = cReadString();
|
|
const char* literal = cReadString();
|
|
if(cConsumeTokenIf(T_OPEN_BRACKET)) {
|
|
if(cConsumeTokenIf(T_OPEN_BRACKET)) {
|
|
@@ -369,18 +315,18 @@ static DataType cLiteral() {
|
|
}
|
|
}
|
|
return dt;
|
|
return dt;
|
|
}
|
|
}
|
|
- Variable* v = vSearch(&vars, literal);
|
|
|
|
- if(v == NULL) {
|
|
|
|
|
|
+ Variable v;
|
|
|
|
+ if(vsSearch(&vars, &v, literal)) {
|
|
cNotDeclared(literal);
|
|
cNotDeclared(literal);
|
|
}
|
|
}
|
|
- Variable sv;
|
|
|
|
- cWalkStruct(v, &sv);
|
|
|
|
|
|
+ cReference(&v, 0);
|
|
if(cConsumeTokenIf(T_INCREMENT)) {
|
|
if(cConsumeTokenIf(T_INCREMENT)) {
|
|
- return cPostChange(v, 1, "++");
|
|
|
|
|
|
+ return cPostChange(&v, 1, "++");
|
|
} else if(cConsumeTokenIf(T_DECREMENT)) {
|
|
} else if(cConsumeTokenIf(T_DECREMENT)) {
|
|
- return cPostChange(v, -1, "--");
|
|
|
|
|
|
+ return cPostChange(&v, -1, "--");
|
|
}
|
|
}
|
|
- return cLoadVariable(v, &sv);
|
|
|
|
|
|
+ cLoadRef(&v);
|
|
|
|
+ return v.type;
|
|
}
|
|
}
|
|
|
|
|
|
static DataType cBracketPrimary() {
|
|
static DataType cBracketPrimary() {
|
|
@@ -417,21 +363,22 @@ static DataType cPrimary() {
|
|
static DataType cPreChange(int change, const char* name) {
|
|
static DataType cPreChange(int change, const char* name) {
|
|
cConsumeToken(T_LITERAL);
|
|
cConsumeToken(T_LITERAL);
|
|
const char* literal = cReadString();
|
|
const char* literal = cReadString();
|
|
- Variable* v = vSearch(&vars, literal);
|
|
|
|
- if(v == NULL) {
|
|
|
|
|
|
+ Variable v;
|
|
|
|
+ if(vsSearch(&vars, &v, literal)) {
|
|
cNotDeclared(literal);
|
|
cNotDeclared(literal);
|
|
- } else if(!dtCompare(v->type, dtInt())) {
|
|
|
|
|
|
+ }
|
|
|
|
+ cReference(&v, 0);
|
|
|
|
+ if(!dtCompare(v.type, dtInt())) {
|
|
cError("%s needs an int", name);
|
|
cError("%s needs an int", name);
|
|
}
|
|
}
|
|
- cAddOperation(OP_LOAD_INT);
|
|
|
|
- cAddInt(v->address);
|
|
|
|
|
|
+ cAddOperation(OP_DUPLICATE_REFERENCE);
|
|
|
|
+ cAddOperation(OP_DUPLICATE_REFERENCE);
|
|
|
|
+ cAddOperation(OP_REF_LOAD_INT);
|
|
cAddOperation(OP_PUSH_INT);
|
|
cAddOperation(OP_PUSH_INT);
|
|
cAddInt(change);
|
|
cAddInt(change);
|
|
cAddOperation(OP_ADD_INT);
|
|
cAddOperation(OP_ADD_INT);
|
|
cAddOperation(OP_STORE_INT);
|
|
cAddOperation(OP_STORE_INT);
|
|
- cAddInt(v->address);
|
|
|
|
- cAddOperation(OP_LOAD_INT);
|
|
|
|
- cAddInt(v->address);
|
|
|
|
|
|
+ cAddOperation(OP_REF_LOAD_INT);
|
|
return dtInt();
|
|
return dtInt();
|
|
}
|
|
}
|
|
|
|
|
|
@@ -473,18 +420,26 @@ static DataType cPreUnary() {
|
|
} else if(cConsumeTokenIf(T_BIT_AND)) {
|
|
} else if(cConsumeTokenIf(T_BIT_AND)) {
|
|
cConsumeToken(T_LITERAL);
|
|
cConsumeToken(T_LITERAL);
|
|
const char* literal = cReadString();
|
|
const char* literal = cReadString();
|
|
- Variable* v = vSearch(&vars, literal);
|
|
|
|
- if(v == NULL) {
|
|
|
|
|
|
+ Variable v;
|
|
|
|
+ if(vsSearch(&vars, &v, literal)) {
|
|
cNotDeclared(literal);
|
|
cNotDeclared(literal);
|
|
}
|
|
}
|
|
- if(v->type.reference) {
|
|
|
|
- cAddOperation(OP_LOAD_INT);
|
|
|
|
- cAddInt(v->address);
|
|
|
|
- } else {
|
|
|
|
- cAddOperation(OP_VAR_REF);
|
|
|
|
- cAddInt(v->address);
|
|
|
|
|
|
+ cReference(&v, 0);
|
|
|
|
+ return dtDereference(v.type);
|
|
|
|
+ } else if(cConsumeTokenIf(T_MUL)) {
|
|
|
|
+ int c = 1;
|
|
|
|
+ while(cConsumeTokenIf(T_MUL)) {
|
|
|
|
+ c++;
|
|
|
|
+ }
|
|
|
|
+ cConsumeToken(T_LITERAL);
|
|
|
|
+ const char* literal = cReadString();
|
|
|
|
+ Variable v;
|
|
|
|
+ if(vsSearch(&vars, &v, literal)) {
|
|
|
|
+ cNotDeclared(literal);
|
|
}
|
|
}
|
|
- return dtToReference(v->type);
|
|
|
|
|
|
+ cReference(&v, c);
|
|
|
|
+ cLoadRef(&v);
|
|
|
|
+ return v.type;
|
|
}
|
|
}
|
|
return cPrimary();
|
|
return cPrimary();
|
|
}
|
|
}
|
|
@@ -650,34 +605,71 @@ static DataType cExpression() {
|
|
return cOr();
|
|
return cOr();
|
|
}
|
|
}
|
|
|
|
|
|
-static void cOperationSet(Variable* v, Variable* sv, const TypedOp* op) {
|
|
|
|
- DataType a = cLoadVariable(v, sv);
|
|
|
|
- DataType b = cExpression();
|
|
|
|
- cAddTypeOperation(a, b, op);
|
|
|
|
- cStoreVariable(v, sv, b, "=");
|
|
|
|
|
|
+static void cOperationSet(Variable* v, const TypedOp* op) {
|
|
|
|
+ cAddOperation(OP_DUPLICATE_REFERENCE);
|
|
|
|
+ cLoadRef(v);
|
|
|
|
+ DataType dt = cExpression();
|
|
|
|
+ cAddTypeOperation(v->type, dt, op);
|
|
|
|
+ cStore(v, dt, "=");
|
|
}
|
|
}
|
|
|
|
|
|
static void cAddPostLineChange(Variable* v, int change, const char* name) {
|
|
static void cAddPostLineChange(Variable* v, int change, const char* name) {
|
|
if(!dtCompare(v->type, dtInt())) {
|
|
if(!dtCompare(v->type, dtInt())) {
|
|
cError("%s needs an int", name);
|
|
cError("%s needs an int", name);
|
|
}
|
|
}
|
|
- cAddOperation(OP_LOAD_INT);
|
|
|
|
- cAddInt(v->address);
|
|
|
|
|
|
+ cAddOperation(OP_DUPLICATE_REFERENCE);
|
|
|
|
+ cAddOperation(OP_REF_LOAD_INT);
|
|
cAddOperation(OP_PUSH_INT);
|
|
cAddOperation(OP_PUSH_INT);
|
|
cAddInt(change);
|
|
cAddInt(change);
|
|
cAddOperation(OP_ADD_INT);
|
|
cAddOperation(OP_ADD_INT);
|
|
cAddOperation(OP_STORE_INT);
|
|
cAddOperation(OP_STORE_INT);
|
|
- cAddInt(v->address);
|
|
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static DataType cExtendType(DataType dt) {
|
|
|
|
+ while(cConsumeTokenIf(T_MUL)) {
|
|
|
|
+ dt = dtDereference(dt);
|
|
|
|
+ }
|
|
|
|
+ return dt;
|
|
}
|
|
}
|
|
|
|
|
|
static void cDeclareStruct(Struct* st) {
|
|
static void cDeclareStruct(Struct* st) {
|
|
|
|
+ DataType dt = cExtendType(dtStruct(st));
|
|
cConsumeToken(T_LITERAL);
|
|
cConsumeToken(T_LITERAL);
|
|
const char* var = cReadString();
|
|
const char* var = cReadString();
|
|
- Variable* v = vSearchScope(&vars, var);
|
|
|
|
- if(v != NULL) {
|
|
|
|
|
|
+ if(vsInScope(&vars, var)) {
|
|
cDeclared(var);
|
|
cDeclared(var);
|
|
}
|
|
}
|
|
- vAdd(&vars, var, dtStruct(st), &structs);
|
|
|
|
|
|
+ Variable* vp = vsAdd(&vars, var, dt, &structs);
|
|
|
|
+ if(dtIsPointer(dt)) {
|
|
|
|
+ cConsumeToken(T_SET);
|
|
|
|
+ cReference(vp, 0);
|
|
|
|
+ cStore(vp, cExpression(), "=");
|
|
|
|
+ }
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static void cLineVariable(const char* name, int dimension) {
|
|
|
|
+ Variable v;
|
|
|
|
+ if(vsSearch(&vars, &v, name)) {
|
|
|
|
+ cNotDeclared(name);
|
|
|
|
+ }
|
|
|
|
+ cReference(&v, dimension);
|
|
|
|
+ Token t = cReadTokenAndLine();
|
|
|
|
+ switch(t) {
|
|
|
|
+ case T_SET: cStore(&v, cExpression(), "="); break;
|
|
|
|
+ case T_ADD_SET: cOperationSet(&v, &TYPED_ADD); break;
|
|
|
|
+ case T_SUB_SET: cOperationSet(&v, &TYPED_SUB); break;
|
|
|
|
+ case T_MUL_SET: cOperationSet(&v, &TYPED_MUL); break;
|
|
|
|
+ case T_DIV_SET: cOperationSet(&v, &TYPED_DIV); break;
|
|
|
|
+ case T_MOD_SET: cOperationSet(&v, &TYPED_MOD); break;
|
|
|
|
+ case T_BIT_AND_SET: cOperationSet(&v, &TYPED_BIT_AND); break;
|
|
|
|
+ case T_BIT_OR_SET: cOperationSet(&v, &TYPED_BIT_OR); break;
|
|
|
|
+ case T_BIT_XOR_SET: cOperationSet(&v, &TYPED_BIT_XOR); break;
|
|
|
|
+ case T_LEFT_SHIFT_SET: cOperationSet(&v, &TYPED_LEFT_SHIFT); break;
|
|
|
|
+ case T_RIGHT_SHIFT_SET: cOperationSet(&v, &TYPED_RIGHT_SHIFT); break;
|
|
|
|
+ case T_INCREMENT: cAddPostLineChange(&v, 1, "++"); break;
|
|
|
|
+ case T_DECREMENT: cAddPostLineChange(&v, -1, "--"); break;
|
|
|
|
+ default: cUnexpectedToken(t);
|
|
|
|
+ }
|
|
}
|
|
}
|
|
|
|
|
|
static void cLineLiteral() {
|
|
static void cLineLiteral() {
|
|
@@ -694,32 +686,7 @@ static void cLineLiteral() {
|
|
cDeclareStruct(st);
|
|
cDeclareStruct(st);
|
|
return;
|
|
return;
|
|
}
|
|
}
|
|
- Variable* v = vSearch(&vars, literal);
|
|
|
|
- if(v == NULL) {
|
|
|
|
- cNotDeclared(literal);
|
|
|
|
- }
|
|
|
|
- Variable sv;
|
|
|
|
- sv.type = dtVoid();
|
|
|
|
- cWalkStruct(v, &sv);
|
|
|
|
- Token t = cReadTokenAndLine();
|
|
|
|
- switch(t) {
|
|
|
|
- case T_SET: cStoreVariable(v, &sv, cExpression(), "="); break;
|
|
|
|
- case T_ADD_SET: cOperationSet(v, &sv, &TYPED_ADD); break;
|
|
|
|
- case T_SUB_SET: cOperationSet(v, &sv, &TYPED_SUB); break;
|
|
|
|
- case T_MUL_SET: cOperationSet(v, &sv, &TYPED_MUL); break;
|
|
|
|
- case T_DIV_SET: cOperationSet(v, &sv, &TYPED_DIV); break;
|
|
|
|
- case T_MOD_SET: cOperationSet(v, &sv, &TYPED_MOD); break;
|
|
|
|
- case T_BIT_AND_SET: cOperationSet(v, &sv, &TYPED_BIT_AND); break;
|
|
|
|
- case T_BIT_OR_SET: cOperationSet(v, &sv, &TYPED_BIT_OR); break;
|
|
|
|
- case T_BIT_XOR_SET: cOperationSet(v, &sv, &TYPED_BIT_XOR); break;
|
|
|
|
- case T_LEFT_SHIFT_SET: cOperationSet(v, &sv, &TYPED_LEFT_SHIFT); break;
|
|
|
|
- case T_RIGHT_SHIFT_SET:
|
|
|
|
- cOperationSet(v, &sv, &TYPED_RIGHT_SHIFT);
|
|
|
|
- break;
|
|
|
|
- case T_INCREMENT: cAddPostLineChange(v, 1, "++"); break;
|
|
|
|
- case T_DECREMENT: cAddPostLineChange(v, -1, "--"); break;
|
|
|
|
- default: cUnexpectedToken(t);
|
|
|
|
- }
|
|
|
|
|
|
+ cLineVariable(literal, 0);
|
|
}
|
|
}
|
|
|
|
|
|
static void cLine(Token t);
|
|
static void cLine(Token t);
|
|
@@ -738,9 +705,9 @@ static void cConsumeBody() {
|
|
|
|
|
|
static void cConsumeScope() {
|
|
static void cConsumeScope() {
|
|
Scope scope;
|
|
Scope scope;
|
|
- vEnterScope(&vars, &scope);
|
|
|
|
|
|
+ vsEnterScope(&vars, &scope);
|
|
cConsumeBody();
|
|
cConsumeBody();
|
|
- vLeaveScope(&vars, &scope);
|
|
|
|
|
|
+ vsLeaveScope(&vars, &scope);
|
|
}
|
|
}
|
|
|
|
|
|
static void cAddReturn(Operation op) {
|
|
static void cAddReturn(Operation op) {
|
|
@@ -840,41 +807,28 @@ static void cWhile() {
|
|
cConsumeBreaks(breakStart, code->length);
|
|
cConsumeBreaks(breakStart, code->length);
|
|
}
|
|
}
|
|
|
|
|
|
-static DataType cExtendType(DataType dt) {
|
|
|
|
- int dimension = 0;
|
|
|
|
- while(cConsumeTokenIf(T_MUL)) {
|
|
|
|
- dimension++;
|
|
|
|
- }
|
|
|
|
- if(dimension > 0) {
|
|
|
|
- dt = dtToArray(dt, dimension);
|
|
|
|
- }
|
|
|
|
- if(cConsumeTokenIf(T_BIT_AND)) {
|
|
|
|
- dt = dtToReference(dt);
|
|
|
|
- }
|
|
|
|
- return dt;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
static void cDeclare(DataType dt) {
|
|
static void cDeclare(DataType dt) {
|
|
dt = cExtendType(dt);
|
|
dt = cExtendType(dt);
|
|
cConsumeToken(T_LITERAL);
|
|
cConsumeToken(T_LITERAL);
|
|
const char* var = cReadString();
|
|
const char* var = cReadString();
|
|
- Variable* v = vSearchScope(&vars, var);
|
|
|
|
- if(v != NULL) {
|
|
|
|
|
|
+ if(vsInScope(&vars, var)) {
|
|
cDeclared(var);
|
|
cDeclared(var);
|
|
}
|
|
}
|
|
- v = vAdd(&vars, var, dt, &structs);
|
|
|
|
|
|
+ Variable* vp = vsAdd(&vars, var, dt, &structs);
|
|
cConsumeToken(T_SET);
|
|
cConsumeToken(T_SET);
|
|
- cStore(v, cExpression(), "=");
|
|
|
|
|
|
+ cReference(vp, 0);
|
|
|
|
+ cStore(vp, cExpression(), "=");
|
|
}
|
|
}
|
|
|
|
|
|
static void cAddPreLineChange(int change, const char* name) {
|
|
static void cAddPreLineChange(int change, const char* name) {
|
|
cConsumeToken(T_LITERAL);
|
|
cConsumeToken(T_LITERAL);
|
|
const char* literal = cReadString();
|
|
const char* literal = cReadString();
|
|
- Variable* v = vSearch(&vars, literal);
|
|
|
|
- if(v == NULL) {
|
|
|
|
|
|
+ Variable v;
|
|
|
|
+ if(vsSearch(&vars, &v, literal)) {
|
|
cNotDeclared(literal);
|
|
cNotDeclared(literal);
|
|
}
|
|
}
|
|
- cAddPostLineChange(v, change, name);
|
|
|
|
|
|
+ cReference(&v, 0);
|
|
|
|
+ cAddPostLineChange(&v, change, name);
|
|
}
|
|
}
|
|
|
|
|
|
static void cLineExpression(Token t) {
|
|
static void cLineExpression(Token t) {
|
|
@@ -885,13 +839,23 @@ static void cLineExpression(Token t) {
|
|
case T_FLOAT: cDeclare(dtFloat()); break;
|
|
case T_FLOAT: cDeclare(dtFloat()); break;
|
|
case T_INCREMENT: cAddPreLineChange(1, "++"); break;
|
|
case T_INCREMENT: cAddPreLineChange(1, "++"); break;
|
|
case T_DECREMENT: cAddPreLineChange(-1, "--"); break;
|
|
case T_DECREMENT: cAddPreLineChange(-1, "--"); break;
|
|
|
|
+ case T_MUL:
|
|
|
|
+ {
|
|
|
|
+ int c = 1;
|
|
|
|
+ while(cConsumeTokenIf(T_MUL)) {
|
|
|
|
+ c++;
|
|
|
|
+ }
|
|
|
|
+ cConsumeToken(T_LITERAL);
|
|
|
|
+ cLineVariable(cReadString(), c);
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
default: cUnexpectedToken(t);
|
|
default: cUnexpectedToken(t);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
static void cFor() {
|
|
static void cFor() {
|
|
Scope scope;
|
|
Scope scope;
|
|
- vEnterScope(&vars, &scope);
|
|
|
|
|
|
+ vsEnterScope(&vars, &scope);
|
|
|
|
|
|
cConsumeToken(T_OPEN_BRACKET);
|
|
cConsumeToken(T_OPEN_BRACKET);
|
|
cLineExpression(cReadTokenAndLine());
|
|
cLineExpression(cReadTokenAndLine());
|
|
@@ -925,7 +889,7 @@ static void cFor() {
|
|
cSetInt(end, code->length);
|
|
cSetInt(end, code->length);
|
|
cConsumeBreaks(breakStart, code->length);
|
|
cConsumeBreaks(breakStart, code->length);
|
|
|
|
|
|
- vLeaveScope(&vars, &scope);
|
|
|
|
|
|
+ vsLeaveScope(&vars, &scope);
|
|
}
|
|
}
|
|
|
|
|
|
static void cBreak() {
|
|
static void cBreak() {
|
|
@@ -979,11 +943,10 @@ static void cFunctionAddArgument(Function* f, DataType dt) {
|
|
dt = cExtendType(dt);
|
|
dt = cExtendType(dt);
|
|
cConsumeToken(T_LITERAL);
|
|
cConsumeToken(T_LITERAL);
|
|
const char* name = cReadString();
|
|
const char* name = cReadString();
|
|
- Variable* v = vSearchScope(&vars, name);
|
|
|
|
- if(v != NULL) {
|
|
|
|
|
|
+ if(vsInScope(&vars, name)) {
|
|
cDeclared(name);
|
|
cDeclared(name);
|
|
}
|
|
}
|
|
- vAdd(&vars, name, dt, &structs);
|
|
|
|
|
|
+ vsAdd(&vars, name, dt, &structs);
|
|
if(fAddArgument(f, dt, &structs)) {
|
|
if(fAddArgument(f, dt, &structs)) {
|
|
cTooMuchArguments();
|
|
cTooMuchArguments();
|
|
}
|
|
}
|
|
@@ -1065,7 +1028,7 @@ static void cBuildFunction(Function* f, DataType rType) {
|
|
cConsumeToken(T_LITERAL);
|
|
cConsumeToken(T_LITERAL);
|
|
fInit(f, cReadString(), line);
|
|
fInit(f, cReadString(), line);
|
|
f->returnType = rType;
|
|
f->returnType = rType;
|
|
- vReset(&vars);
|
|
|
|
|
|
+ vsReset(&vars);
|
|
cFunctionArguments(f);
|
|
cFunctionArguments(f);
|
|
}
|
|
}
|
|
|
|
|
|
@@ -1173,7 +1136,7 @@ static void cAllocAndCompile() {
|
|
forWhileStack = 0;
|
|
forWhileStack = 0;
|
|
breakIndex = 0;
|
|
breakIndex = 0;
|
|
returnType = dtVoid();
|
|
returnType = dtVoid();
|
|
- vInit(&vars);
|
|
|
|
|
|
+ vsInit(&vars);
|
|
fsInit(&functions);
|
|
fsInit(&functions);
|
|
fsInit(&functionQueue);
|
|
fsInit(&functionQueue);
|
|
stsInit(&structs);
|
|
stsInit(&structs);
|
|
@@ -1184,7 +1147,7 @@ static void cAllocAndCompile() {
|
|
stsDelete(&structs);
|
|
stsDelete(&structs);
|
|
fsDelete(&functionQueue);
|
|
fsDelete(&functionQueue);
|
|
fsDelete(&functions);
|
|
fsDelete(&functions);
|
|
- vDelete(&vars);
|
|
|
|
|
|
+ vsDelete(&vars);
|
|
}
|
|
}
|
|
|
|
|
|
ByteCode* cCompile() {
|
|
ByteCode* cCompile() {
|