Add .cpp mode and namespace/using
This commit is contained in:
parent
433270f90f
commit
fd391690b9
|
@ -12,8 +12,8 @@ CompilationUnits::CompilationUnits(Errors * errors)
|
|||
{
|
||||
mCompilationUnits = nullptr;
|
||||
mPendingUnits = nullptr;
|
||||
mScope = new DeclarationScope(nullptr);
|
||||
mRuntimeScope = new DeclarationScope(nullptr);
|
||||
mScope = new DeclarationScope(nullptr, SLEVEL_GLOBAL);
|
||||
mRuntimeScope = new DeclarationScope(nullptr, SLEVEL_GLOBAL);
|
||||
mStartup = nullptr;
|
||||
|
||||
for (int i = 0; i < 256; i++)
|
||||
|
|
|
@ -145,6 +145,10 @@ bool Compiler::ParseSource(void)
|
|||
for (int i = 0; i < mDefines.Size(); i++)
|
||||
scanner->AddMacro(mDefines[i].mIdent, mDefines[i].mValue);
|
||||
|
||||
scanner->mCompilerOptions = mCompilerOptions;
|
||||
|
||||
scanner->NextToken();
|
||||
|
||||
Parser* parser = new Parser(mErrors, scanner, mCompilationUnits);
|
||||
|
||||
parser->mCompilerOptions = mCompilerOptions;
|
||||
|
@ -1161,25 +1165,25 @@ bool Compiler::WriteDbjFile(const char* filename)
|
|||
{
|
||||
case DT_TYPE_INTEGER:
|
||||
if (dec->mFlags & DTF_SIGNED)
|
||||
fprintf(file, "\t\t{\"name\": \"%s\", \"typeid\": %d, \"size\": %d, \"type\": \"int\"}", dec->mIdent ? dec->mIdent->mString : "", i, dec->mSize);
|
||||
fprintf(file, "\t\t{\"name\": \"%s\", \"typeid\": %d, \"size\": %d, \"type\": \"int\"}", dec->mQualIdent ? dec->mQualIdent->mString : "", i, dec->mSize);
|
||||
else
|
||||
fprintf(file, "\t\t{\"name\": \"%s\", \"typeid\": %d, \"size\": %d, \"type\": \"uint\"}", dec->mIdent ? dec->mIdent->mString : "", i, dec->mSize);
|
||||
fprintf(file, "\t\t{\"name\": \"%s\", \"typeid\": %d, \"size\": %d, \"type\": \"uint\"}", dec->mQualIdent ? dec->mQualIdent->mString : "", i, dec->mSize);
|
||||
break;
|
||||
case DT_TYPE_FLOAT:
|
||||
fprintf(file, "\t\t{\"name\": \"%s\", \"typeid\": %d, \"size\": %d, \"type\": \"float\"}", dec->mIdent ? dec->mIdent->mString : "", i, dec->mSize);
|
||||
fprintf(file, "\t\t{\"name\": \"%s\", \"typeid\": %d, \"size\": %d, \"type\": \"float\"}", dec->mQualIdent ? dec->mQualIdent->mString : "", i, dec->mSize);
|
||||
break;
|
||||
case DT_TYPE_BOOL:
|
||||
fprintf(file, "\t\t{\"name\": \"%s\", \"typeid\": %d, \"size\": %d, \"type\": \"bool\"}", dec->mIdent ? dec->mIdent->mString : "", i, dec->mSize);
|
||||
fprintf(file, "\t\t{\"name\": \"%s\", \"typeid\": %d, \"size\": %d, \"type\": \"bool\"}", dec->mQualIdent ? dec->mQualIdent->mString : "", i, dec->mSize);
|
||||
break;
|
||||
case DT_TYPE_ARRAY:
|
||||
fprintf(file, "\t\t{\"name\": \"%s\", \"typeid\": %d, \"size\": %d, \"type\": \"array\", \"eid\": %d}", dec->mIdent ? dec->mIdent->mString : "", i, dec->mSize, types.IndexOrPush(dec->mBase));
|
||||
fprintf(file, "\t\t{\"name\": \"%s\", \"typeid\": %d, \"size\": %d, \"type\": \"array\", \"eid\": %d}", dec->mQualIdent ? dec->mQualIdent->mString : "", i, dec->mSize, types.IndexOrPush(dec->mBase));
|
||||
break;
|
||||
case DT_TYPE_POINTER:
|
||||
fprintf(file, "\t\t{\"name\": \"%s\", \"typeid\": %d, \"size\": %d, \"type\": \"ptr\", eid: %d}", dec->mIdent ? dec->mIdent->mString : "", i, dec->mSize, types.IndexOrPush(dec->mBase));
|
||||
fprintf(file, "\t\t{\"name\": \"%s\", \"typeid\": %d, \"size\": %d, \"type\": \"ptr\", eid: %d}", dec->mQualIdent ? dec->mQualIdent->mString : "", i, dec->mSize, types.IndexOrPush(dec->mBase));
|
||||
break;
|
||||
case DT_TYPE_ENUM:
|
||||
{
|
||||
fprintf(file, "\t\t{\"name\": \"%s\", \"typeid\": %d, \"size\": %d, \"type\": \"enum\",\"members\": [\n", dec->mIdent ? dec->mIdent->mString : "", i, dec->mSize);
|
||||
fprintf(file, "\t\t{\"name\": \"%s\", \"typeid\": %d, \"size\": %d, \"type\": \"enum\",\"members\": [\n", dec->mQualIdent ? dec->mQualIdent->mString : "", i, dec->mSize);
|
||||
bool tfirst = true;
|
||||
Declaration* mdec = dec->mParams;
|
||||
while (mdec)
|
||||
|
@ -1201,7 +1205,7 @@ bool Compiler::WriteDbjFile(const char* filename)
|
|||
break;
|
||||
case DT_TYPE_STRUCT:
|
||||
{
|
||||
fprintf(file, "\t\t{\"name\": \"%s\", \"typeid\": %d, \"size\": %d, \"type\": \"struct\",\"members\": [\n", dec->mIdent ? dec->mIdent->mString : "", i, dec->mSize);
|
||||
fprintf(file, "\t\t{\"name\": \"%s\", \"typeid\": %d, \"size\": %d, \"type\": \"struct\",\"members\": [\n", dec->mQualIdent ? dec->mQualIdent->mString : "", i, dec->mSize);
|
||||
bool tfirst = true;
|
||||
Declaration* mdec = dec->mParams;
|
||||
while (mdec)
|
||||
|
@ -1218,7 +1222,7 @@ bool Compiler::WriteDbjFile(const char* filename)
|
|||
}
|
||||
break;
|
||||
default:
|
||||
fprintf(file, "\t\t{\"name\": \"%s\", \"typeid\": %d, \"size\": %d}", dec->mIdent ? dec->mIdent->mString : "", i, dec->mSize);
|
||||
fprintf(file, "\t\t{\"name\": \"%s\", \"typeid\": %d, \"size\": %d}", dec->mQualIdent ? dec->mQualIdent->mString : "", i, dec->mSize);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -34,6 +34,9 @@ static const uint64 COPT_VERBOSE3 = 1ULL << 50;
|
|||
|
||||
static const uint64 COPT_DEBUGINFO = 1ULL << 51;
|
||||
|
||||
static const uint64 COPT_CPLUSPLUS = 1ULL << 52;
|
||||
|
||||
|
||||
|
||||
static const uint64 COPT_DEFAULT = COPT_OPTIMIZE_BASIC | COPT_OPTIMIZE_INLINE | COPT_OPTIMIZE_CONST_EXPRESSIONS;
|
||||
|
||||
|
|
|
@ -1,8 +1,10 @@
|
|||
#include "Declaration.h"
|
||||
|
||||
DeclarationScope::DeclarationScope(DeclarationScope* parent)
|
||||
DeclarationScope::DeclarationScope(DeclarationScope* parent, ScopeLevel level, const Ident* name)
|
||||
{
|
||||
mParent = parent;
|
||||
mLevel = level;
|
||||
mName = name;
|
||||
mHashSize = 0;
|
||||
mHashFill = 0;
|
||||
mHash = nullptr;
|
||||
|
@ -13,6 +15,25 @@ DeclarationScope::~DeclarationScope(void)
|
|||
delete[] mHash;
|
||||
}
|
||||
|
||||
const Ident* DeclarationScope::Mangle(const Ident* ident) const
|
||||
{
|
||||
if (mName)
|
||||
{
|
||||
char buffer[200];
|
||||
strcpy_s(buffer, mName->mString);
|
||||
strcat_s(buffer, "::");
|
||||
strcat_s(buffer, ident->mString);
|
||||
return Ident::Unique(buffer);
|
||||
}
|
||||
else
|
||||
return ident;
|
||||
}
|
||||
|
||||
void DeclarationScope::UseScope(DeclarationScope* scope)
|
||||
{
|
||||
mUsed.Push(scope);
|
||||
}
|
||||
|
||||
Declaration * DeclarationScope::Insert(const Ident* ident, Declaration* dec)
|
||||
{
|
||||
if (!mHash)
|
||||
|
@ -79,6 +100,13 @@ Declaration* DeclarationScope::Lookup(const Ident* ident)
|
|||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < mUsed.Size(); i++)
|
||||
{
|
||||
Declaration* dec = mUsed[i]->Lookup(ident);
|
||||
if (dec)
|
||||
return dec;
|
||||
}
|
||||
|
||||
return mParent ? mParent->Lookup(ident) : nullptr;
|
||||
}
|
||||
|
||||
|
@ -602,7 +630,8 @@ Expression* Expression::ConstantFold(Errors * errors)
|
|||
}
|
||||
|
||||
Declaration::Declaration(const Location& loc, DecType type)
|
||||
: mLocation(loc), mEndLocation(loc), mType(type), mScope(nullptr), mData(nullptr), mIdent(nullptr), mSize(0), mOffset(0), mFlags(0), mComplexity(0), mLocalSize(0),
|
||||
: mLocation(loc), mEndLocation(loc), mType(type), mScope(nullptr), mData(nullptr), mIdent(nullptr), mQualIdent(nullptr),
|
||||
mSize(0), mOffset(0), mFlags(0), mComplexity(0), mLocalSize(0),
|
||||
mBase(nullptr), mParams(nullptr), mValue(nullptr), mNext(nullptr), mConst(nullptr),
|
||||
mVarIndex(-1), mLinkerObject(nullptr), mCallers(nullptr), mCalled(nullptr), mAlignment(1),
|
||||
mInteger(0), mNumber(0), mMinValue(-0x80000000LL), mMaxValue(0x7fffffffLL), mFastCallBase(0), mFastCallSize(0), mStride(0), mStripe(1),
|
||||
|
@ -632,6 +661,7 @@ Declaration* Declaration::Clone(void)
|
|||
ndec->mScope = mScope;
|
||||
ndec->mParams = mParams;
|
||||
ndec->mIdent = mIdent;
|
||||
ndec->mQualIdent = mQualIdent;
|
||||
ndec->mValue = mValue;
|
||||
ndec->mVarIndex = mVarIndex;
|
||||
ndec->mLinkerObject = mLinkerObject;
|
||||
|
@ -689,6 +719,7 @@ Declaration* Declaration::ToStriped(int stripe)
|
|||
ndec->mStripe = stripe;
|
||||
ndec->mFlags = mFlags;
|
||||
ndec->mIdent = mIdent;
|
||||
ndec->mQualIdent = mQualIdent;
|
||||
|
||||
if (mType == DT_ELEMENT)
|
||||
ndec->mBase = mBase->ToStriped(stripe);
|
||||
|
@ -697,7 +728,7 @@ Declaration* Declaration::ToStriped(int stripe)
|
|||
|
||||
if (mType == DT_TYPE_STRUCT)
|
||||
{
|
||||
ndec->mScope = new DeclarationScope(nullptr);
|
||||
ndec->mScope = new DeclarationScope(nullptr, mScope->mLevel);
|
||||
Declaration * p = mParams;
|
||||
Declaration* prev = nullptr;
|
||||
while (p)
|
||||
|
@ -743,6 +774,7 @@ Declaration* Declaration::ToConstType(void)
|
|||
ndec->mScope = mScope;
|
||||
ndec->mParams = mParams;
|
||||
ndec->mIdent = mIdent;
|
||||
ndec->mQualIdent = mQualIdent;
|
||||
mConst = ndec;
|
||||
}
|
||||
|
||||
|
|
|
@ -45,7 +45,8 @@ enum DecType
|
|||
DT_LABEL,
|
||||
DT_VARIABLE_REF,
|
||||
DT_FUNCTION_REF,
|
||||
DT_LABEL_REF
|
||||
DT_LABEL_REF,
|
||||
DT_NAMESPACE,
|
||||
};
|
||||
|
||||
// TypeFlags
|
||||
|
@ -96,17 +97,34 @@ static const uint64 DTF_VAR_ALIASING = (1ULL << 48);
|
|||
|
||||
class Declaration;
|
||||
|
||||
enum ScopeLevel
|
||||
{
|
||||
SLEVEL_GLOBAL,
|
||||
SLEVEL_STATIC,
|
||||
SLEVEL_NAMESPACE,
|
||||
SLEVEL_CLASS,
|
||||
SLEVEL_FUNCTION,
|
||||
SLEVEL_LOCAL
|
||||
};
|
||||
|
||||
class DeclarationScope
|
||||
{
|
||||
public:
|
||||
DeclarationScope(DeclarationScope * parent);
|
||||
DeclarationScope(DeclarationScope * parent, ScopeLevel level, const Ident * name = nullptr);
|
||||
~DeclarationScope(void);
|
||||
|
||||
const Ident* Mangle(const Ident* ident) const;
|
||||
|
||||
Declaration* Insert(const Ident* ident, Declaration* dec);
|
||||
Declaration* Lookup(const Ident* ident);
|
||||
|
||||
void End(const Location & loc);
|
||||
|
||||
void UseScope(DeclarationScope* scope);
|
||||
|
||||
ScopeLevel mLevel;
|
||||
const Ident * mName;
|
||||
|
||||
DeclarationScope* mParent;
|
||||
protected:
|
||||
struct Entry
|
||||
|
@ -116,6 +134,7 @@ protected:
|
|||
};
|
||||
Entry * mHash;
|
||||
int mHashSize, mHashFill;
|
||||
ExpandingArray<DeclarationScope*> mUsed;
|
||||
};
|
||||
|
||||
enum ExpressionType
|
||||
|
@ -199,7 +218,7 @@ public:
|
|||
int64 mInteger, mMinValue, mMaxValue;
|
||||
double mNumber;
|
||||
uint64 mFlags, mCompilerOptions;
|
||||
const Ident * mIdent;
|
||||
const Ident * mIdent, * mQualIdent;
|
||||
LinkerSection * mSection;
|
||||
const uint8 * mData;
|
||||
LinkerObject * mLinkerObject;
|
||||
|
|
|
@ -69,6 +69,7 @@ enum ErrorID
|
|||
ERRR_USE_OF_UNINITIALIZED_VARIABLE,
|
||||
ERRR_STRIPE_REQUIRES_FIXED_SIZE_ARRAY,
|
||||
ERRR_CANNOT_FIND_BANK_OF_EXPRESSION,
|
||||
ERRO_NOT_A_NAMESPACE,
|
||||
|
||||
ERRR_STACK_OVERFLOW,
|
||||
ERRR_INVALID_NUMBER,
|
||||
|
|
|
@ -40,21 +40,21 @@ void GlobalAnalyzer::DumpCallGraph(void)
|
|||
for (int j = 0; j < decs.Size(); j++)
|
||||
{
|
||||
if (decs[j]->mType == DT_CONST_FUNCTION)
|
||||
printf("CALL %s[%d, %08llx] -> %d -> %s[%d, %08llx]\n", from->mIdent->mString, from->mComplexity, from->mFlags, calls[j], decs[j]->mIdent->mString, decs[j]->mComplexity, decs[j]->mFlags);
|
||||
printf("CALL %s[%d, %08llx] -> %d -> %s[%d, %08llx]\n", from->mQualIdent->mString, from->mComplexity, from->mFlags, calls[j], decs[j]->mQualIdent->mString, decs[j]->mComplexity, decs[j]->mFlags);
|
||||
else
|
||||
printf("CALL %s[%d, %08llx] -> %d\n", from->mIdent->mString, from->mComplexity, from->mFlags, calls[j]);
|
||||
printf("CALL %s[%d, %08llx] -> %d\n", from->mQualIdent->mString, from->mComplexity, from->mFlags, calls[j]);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("LEAF %d -> %s[%d, %08llx]\n", from->mCallers.Size(), from->mIdent->mString, from->mComplexity, from->mFlags );
|
||||
printf("LEAF %d -> %s[%d, %08llx]\n", from->mCallers.Size(), from->mQualIdent->mString, from->mComplexity, from->mFlags );
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < mGlobalVariables.Size(); i++)
|
||||
{
|
||||
Declaration* var = mGlobalVariables[i];
|
||||
printf("VAR %s[%d, %08llx, %d]\n", var->mIdent->mString, var->mSize, var->mFlags, var->mUseCount);
|
||||
printf("VAR %s[%d, %08llx, %d]\n", var->mQualIdent->mString, var->mSize, var->mFlags, var->mUseCount);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -445,7 +445,7 @@ void GlobalAnalyzer::AnalyzeProcedure(Expression* exp, Declaration* dec)
|
|||
Analyze(exp, dec, false);
|
||||
}
|
||||
else
|
||||
mErrors->Error(dec->mLocation, EERR_UNDEFINED_OBJECT, "Calling undefined function", dec->mIdent);
|
||||
mErrors->Error(dec->mLocation, EERR_UNDEFINED_OBJECT, "Calling undefined function", dec->mQualIdent);
|
||||
|
||||
dec->mFlags &= ~DTF_FUNC_ANALYZING;
|
||||
}
|
||||
|
@ -662,7 +662,7 @@ Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec, boo
|
|||
{
|
||||
procDec->mFlags &= ~DTF_FUNC_INTRSAVE;
|
||||
if (procDec->mFlags & DTF_INTERRUPT)
|
||||
mErrors->Error(exp->mLocation, EWARN_NOT_INTERRUPT_SAFE, "Calling non interrupt safe function", ldec->mIdent);
|
||||
mErrors->Error(exp->mLocation, EWARN_NOT_INTERRUPT_SAFE, "Calling non interrupt safe function", ldec->mQualIdent);
|
||||
}
|
||||
if (!(GetProcFlags(ldec) & DTF_FUNC_PURE))
|
||||
procDec->mFlags &= ~DTF_FUNC_PURE;
|
||||
|
|
|
@ -376,8 +376,8 @@ void InterCodeGenerator::InitGlobalVariable(InterCodeModule * mod, Declaration*
|
|||
InterVariable * var = new InterVariable();
|
||||
var->mOffset = 0;
|
||||
var->mSize = dec->mSize;
|
||||
var->mLinkerObject = mLinker->AddObject(dec->mLocation, dec->mIdent, dec->mSection, LOT_DATA, dec->mAlignment);
|
||||
var->mIdent = dec->mIdent;
|
||||
var->mLinkerObject = mLinker->AddObject(dec->mLocation, dec->mQualIdent, dec->mSection, LOT_DATA, dec->mAlignment);
|
||||
var->mIdent = dec->mQualIdent;
|
||||
|
||||
Declaration* decb = dec->mBase;
|
||||
while (decb && decb->mType == DT_TYPE_ARRAY)
|
||||
|
@ -437,7 +437,7 @@ void InterCodeGenerator::TranslateAssembler(InterCodeModule* mod, Expression* ex
|
|||
|
||||
Declaration* dec = exp->mDecValue;
|
||||
|
||||
dec->mLinkerObject = mLinker->AddObject(dec->mLocation, dec->mIdent, dec->mSection, LOT_NATIVE_CODE);
|
||||
dec->mLinkerObject = mLinker->AddObject(dec->mLocation, dec->mQualIdent, dec->mSection, LOT_NATIVE_CODE);
|
||||
|
||||
uint8* d = dec->mLinkerObject->AddSpace(osize);
|
||||
|
||||
|
@ -485,7 +485,7 @@ void InterCodeGenerator::TranslateAssembler(InterCodeModule* mod, Expression* ex
|
|||
dec->mLinkerObject->AddReference(ref);
|
||||
}
|
||||
else
|
||||
mErrors->Error(aexp->mLocation, EERR_ASM_INVALD_OPERAND, "Undefined immediate operand", aexp->mBase->mIdent);
|
||||
mErrors->Error(aexp->mLocation, EERR_ASM_INVALD_OPERAND, "Undefined immediate operand", aexp->mBase->mQualIdent);
|
||||
}
|
||||
else if (aexp->mType == DT_VARIABLE_REF)
|
||||
{
|
||||
|
@ -730,7 +730,7 @@ void InterCodeGenerator::TranslateAssembler(InterCodeModule* mod, Expression* ex
|
|||
if (aexp->mBase->mBase)
|
||||
d[offset] = uint8(aexp->mOffset + aexp->mBase->mInteger - offset - 1);
|
||||
else
|
||||
mErrors->Error(aexp->mLocation, EERR_ASM_INVALD_OPERAND, "Undefined immediate operand", aexp->mBase->mIdent);
|
||||
mErrors->Error(aexp->mLocation, EERR_ASM_INVALD_OPERAND, "Undefined immediate operand", aexp->mBase->mQualIdent);
|
||||
}
|
||||
else
|
||||
d[offset] = uint8(aexp->mInteger - offset - 1);
|
||||
|
@ -884,6 +884,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateInline(Declaration* pro
|
|||
ains->mConst.mOperandSize = pdec->mSize;
|
||||
vdec->mSize = ains->mConst.mOperandSize;
|
||||
vdec->mIdent = pdec->mIdent;
|
||||
vdec->mQualIdent = pdec->mQualIdent;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1177,12 +1178,12 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
|||
dec->mVarIndex = proc->mModule->mGlobalVars.Size();
|
||||
InterVariable* var = new InterVariable();
|
||||
var->mIndex = dec->mVarIndex;
|
||||
var->mIdent = dec->mIdent;
|
||||
var->mIdent = dec->mQualIdent;
|
||||
var->mOffset = 0;
|
||||
var->mSize = dec->mSize;
|
||||
if ((dec->mFlags & DTF_VAR_ALIASING) || dec->mBase->mType == DT_TYPE_ARRAY)
|
||||
var->mAliased = true;
|
||||
var->mLinkerObject = mLinker->AddObject(dec->mLocation, dec->mIdent, dec->mSection, LOT_DATA, dec->mAlignment);
|
||||
var->mLinkerObject = mLinker->AddObject(dec->mLocation, dec->mQualIdent, dec->mSection, LOT_DATA, dec->mAlignment);
|
||||
dec->mLinkerObject = var->mLinkerObject;
|
||||
var->mLinkerObject->AddData(dec->mData, dec->mSize);
|
||||
proc->mModule->mGlobalVars.Push(var);
|
||||
|
@ -1209,9 +1210,9 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
|||
var->mSize = dec->mSize;
|
||||
if (dec->mFlags & DTF_VAR_ALIASING)
|
||||
var->mAliased = true;
|
||||
var->mLinkerObject = mLinker->AddObject(dec->mLocation, dec->mIdent, dec->mSection, LOT_DATA, dec->mAlignment);
|
||||
var->mLinkerObject = mLinker->AddObject(dec->mLocation, dec->mQualIdent, dec->mSection, LOT_DATA, dec->mAlignment);
|
||||
dec->mLinkerObject = var->mLinkerObject;
|
||||
var->mIdent = dec->mIdent;
|
||||
var->mIdent = dec->mQualIdent;
|
||||
dec->mVarIndex = proc->mModule->mGlobalVars.Size();
|
||||
var->mIndex = dec->mVarIndex;
|
||||
proc->mModule->mGlobalVars.Push(var);
|
||||
|
@ -2229,7 +2230,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
|||
if (exp->mLeft->mType == EX_CONSTANT && exp->mLeft->mDecValue->mType == DT_CONST_FUNCTION && (exp->mLeft->mDecValue->mFlags & DTF_INTRINSIC))
|
||||
{
|
||||
Declaration* decf = exp->mLeft->mDecValue;
|
||||
const Ident * iname = decf->mIdent;
|
||||
const Ident * iname = decf->mQualIdent;
|
||||
|
||||
if (!strcmp(iname->mString, "fabs"))
|
||||
{
|
||||
|
@ -3657,7 +3658,7 @@ void InterCodeGenerator::BuildInitializer(InterCodeModule * mod, uint8* dp, int
|
|||
var->mSize = dec->mSize;
|
||||
if (dec->mFlags & DTF_VAR_ALIASING)
|
||||
var->mAliased = true;
|
||||
var->mLinkerObject = mLinker->AddObject(dec->mLocation, dec->mIdent, dec->mSection, LOT_DATA, dec->mAlignment);
|
||||
var->mLinkerObject = mLinker->AddObject(dec->mLocation, dec->mQualIdent, dec->mSection, LOT_DATA, dec->mAlignment);
|
||||
dec->mLinkerObject = var->mLinkerObject;
|
||||
var->mLinkerObject->AddData(dec->mData, dec->mSize);
|
||||
mod->mGlobalVars.Push(var);
|
||||
|
@ -3756,7 +3757,7 @@ void InterCodeGenerator::TranslateLogic(Declaration* procType, InterCodeProcedur
|
|||
|
||||
InterCodeProcedure* InterCodeGenerator::TranslateProcedure(InterCodeModule * mod, Expression* exp, Declaration * dec)
|
||||
{
|
||||
InterCodeProcedure* proc = new InterCodeProcedure(mod, dec->mLocation, dec->mIdent, mLinker->AddObject(dec->mLocation, dec->mIdent, dec->mSection, LOT_BYTE_CODE));
|
||||
InterCodeProcedure* proc = new InterCodeProcedure(mod, dec->mLocation, dec->mQualIdent, mLinker->AddObject(dec->mLocation, dec->mQualIdent, dec->mSection, LOT_BYTE_CODE));
|
||||
|
||||
uint64 outerCompilerOptions = mCompilerOptions;
|
||||
mCompilerOptions = dec->mCompilerOptions;
|
||||
|
@ -3845,7 +3846,7 @@ InterCodeProcedure* InterCodeGenerator::TranslateProcedure(InterCodeModule * mod
|
|||
TranslateExpression(dec->mBase, proc, exitBlock, exp, nullptr, nullptr, nullptr);
|
||||
}
|
||||
else
|
||||
mErrors->Error(dec->mLocation, EERR_UNDEFINED_OBJECT, "Calling undefined function", dec->mIdent->mString);
|
||||
mErrors->Error(dec->mLocation, EERR_UNDEFINED_OBJECT, "Calling undefined function", dec->mQualIdent->mString);
|
||||
|
||||
InterInstruction * ins = new InterInstruction(exp ? exp->mEndLocation : dec->mLocation, IC_RETURN);
|
||||
exitBlock->Append(ins);
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
Parser::Parser(Errors* errors, Scanner* scanner, CompilationUnits* compilationUnits)
|
||||
: mErrors(errors), mScanner(scanner), mCompilationUnits(compilationUnits)
|
||||
{
|
||||
mGlobals = new DeclarationScope(compilationUnits->mScope);
|
||||
mGlobals = new DeclarationScope(compilationUnits->mScope, SLEVEL_STATIC);
|
||||
mScope = mGlobals;
|
||||
|
||||
mCodeSection = compilationUnits->mSectionCode;
|
||||
|
@ -63,7 +63,8 @@ Declaration* Parser::ParseStructDeclaration(uint64 flags, DecType dt)
|
|||
if (!dec->mIdent || !dec->mScope)
|
||||
{
|
||||
dec->mIdent = structName;
|
||||
dec->mScope = new DeclarationScope(nullptr);
|
||||
dec->mQualIdent = mScope->Mangle(structName);
|
||||
dec->mScope = new DeclarationScope(nullptr, SLEVEL_CLASS);
|
||||
}
|
||||
|
||||
if (mScanner->mToken == TK_OPEN_BRACE)
|
||||
|
@ -72,7 +73,7 @@ Declaration* Parser::ParseStructDeclaration(uint64 flags, DecType dt)
|
|||
Declaration* mlast = nullptr;
|
||||
for (;;)
|
||||
{
|
||||
Declaration* mdec = ParseDeclaration(false, false);
|
||||
Declaration* mdec = ParseDeclaration(nullptr, false, false);
|
||||
|
||||
int offset = dec->mSize;
|
||||
if (dt == DT_TYPE_UNION)
|
||||
|
@ -265,6 +266,7 @@ Declaration* Parser::ParseBaseTypeDeclaration(uint64 flags)
|
|||
ndec->mScope = dec->mScope;
|
||||
ndec->mParams = dec->mParams;
|
||||
ndec->mIdent = dec->mIdent;
|
||||
ndec->mQualIdent = dec->mQualIdent;
|
||||
dec = ndec;
|
||||
}
|
||||
mScanner->NextToken();
|
||||
|
@ -286,12 +288,13 @@ Declaration* Parser::ParseBaseTypeDeclaration(uint64 flags)
|
|||
dec = new Declaration(mScanner->mLocation, DT_TYPE_ENUM);
|
||||
dec->mFlags = flags;
|
||||
dec->mSize = 1;
|
||||
dec->mScope = new DeclarationScope(nullptr);
|
||||
dec->mScope = new DeclarationScope(nullptr, SLEVEL_CLASS);
|
||||
|
||||
mScanner->NextToken();
|
||||
if (mScanner->mToken == TK_IDENT)
|
||||
{
|
||||
dec->mIdent = mScanner->mTokenIdent;
|
||||
dec->mQualIdent = mScope->Mangle(dec->mIdent);
|
||||
|
||||
if (mScope->Insert(dec->mIdent, dec))
|
||||
mErrors->Error(dec->mLocation, EERR_DUPLICATE_DEFINITION, "Duplicate name", dec->mIdent);
|
||||
|
@ -314,6 +317,7 @@ Declaration* Parser::ParseBaseTypeDeclaration(uint64 flags)
|
|||
if (mScanner->mToken == TK_IDENT)
|
||||
{
|
||||
cdec->mIdent = mScanner->mTokenIdent;
|
||||
cdec->mQualIdent = mScope->Mangle(cdec->mIdent);
|
||||
if (mScope->Insert(cdec->mIdent, cdec) != nullptr)
|
||||
mErrors->Error(mScanner->mLocation, EERR_DUPLICATE_DEFINITION, "Duplicate declaration", mScanner->mTokenIdent->mString);
|
||||
mScanner->NextToken();
|
||||
|
@ -441,6 +445,7 @@ Declaration* Parser::ParsePostfixDeclaration(void)
|
|||
{
|
||||
dec = new Declaration(mScanner->mLocation, DT_VARIABLE);
|
||||
dec->mIdent = mScanner->mTokenIdent;
|
||||
dec->mQualIdent = mScope->Mangle(dec->mIdent);
|
||||
dec->mSection = mBSSection;
|
||||
dec->mBase = nullptr;
|
||||
mScanner->NextToken();
|
||||
|
@ -1005,87 +1010,126 @@ Expression* Parser::ParseInitExpression(Declaration* dtype)
|
|||
return exp;
|
||||
}
|
||||
|
||||
Declaration* Parser::ParseDeclaration(bool variable, bool expression)
|
||||
Declaration* Parser::ParseDeclaration(Declaration * pdec, bool variable, bool expression)
|
||||
{
|
||||
bool definingType = false;
|
||||
uint64 storageFlags = 0, typeFlags = 0;
|
||||
Declaration* bdec;
|
||||
|
||||
if (mScanner->mToken == TK_TYPEDEF)
|
||||
if (pdec)
|
||||
{
|
||||
definingType = true;
|
||||
variable = false;
|
||||
mScanner->NextToken();
|
||||
bdec = pdec;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (;;)
|
||||
if (mScanner->mToken == TK_TYPEDEF)
|
||||
{
|
||||
if (mScanner->mToken == TK_STATIC)
|
||||
definingType = true;
|
||||
variable = false;
|
||||
mScanner->NextToken();
|
||||
}
|
||||
else if (mScanner->mToken == TK_USING)
|
||||
{
|
||||
mScanner->NextToken();
|
||||
if (ConsumeTokenIf(TK_NAMESPACE))
|
||||
{
|
||||
storageFlags |= DTF_STATIC;
|
||||
mScanner->NextToken();
|
||||
}
|
||||
else if (mScanner->mToken == TK_EXTERN)
|
||||
{
|
||||
storageFlags |= DTF_EXTERN;
|
||||
mScanner->NextToken();
|
||||
}
|
||||
else if (mScanner->mToken == TK_ZEROPAGE)
|
||||
{
|
||||
storageFlags |= DTF_ZEROPAGE;
|
||||
mScanner->NextToken();
|
||||
}
|
||||
else if (mScanner->mToken == TK_STRIPED)
|
||||
{
|
||||
storageFlags |= DTF_STRIPED;
|
||||
mScanner->NextToken();
|
||||
}
|
||||
else if (mScanner->mToken == TK_NOINLINE)
|
||||
{
|
||||
storageFlags |= DTF_PREVENT_INLINE;
|
||||
mScanner->NextToken();
|
||||
}
|
||||
else if (mScanner->mToken == TK_INLINE)
|
||||
{
|
||||
storageFlags |= DTF_REQUEST_INLINE;
|
||||
mScanner->NextToken();
|
||||
}
|
||||
else if (mScanner->mToken == TK_EXPORT)
|
||||
{
|
||||
storageFlags |= DTF_EXPORT;
|
||||
mScanner->NextToken();
|
||||
}
|
||||
else if (mScanner->mToken == TK_DYNSTACK)
|
||||
{
|
||||
storageFlags |= DTF_DYNSTACK;
|
||||
mScanner->NextToken();
|
||||
}
|
||||
else if (mScanner->mToken == TK_FASTCALL)
|
||||
{
|
||||
storageFlags |= DTF_FASTCALL;
|
||||
mScanner->NextToken();
|
||||
}
|
||||
else if (mScanner->mToken == TK_NATIVE)
|
||||
{
|
||||
storageFlags |= DTF_NATIVE;
|
||||
mScanner->NextToken();
|
||||
}
|
||||
else if (mScanner->mToken == TK_INTERRUPT)
|
||||
{
|
||||
storageFlags |= DTF_INTERRUPT | DTF_NATIVE;
|
||||
mScanner->NextToken();
|
||||
}
|
||||
else if (mScanner->mToken == TK_HWINTERRUPT)
|
||||
{
|
||||
storageFlags |= DTF_INTERRUPT | DTF_HWINTERRUPT | DTF_NATIVE;
|
||||
mScanner->NextToken();
|
||||
Declaration* dec = ParseQualIdent();
|
||||
if (dec)
|
||||
{
|
||||
if (dec->mType == DT_NAMESPACE)
|
||||
{
|
||||
mScope->UseScope(dec->mScope);
|
||||
}
|
||||
else
|
||||
mErrors->Error(mScanner->mLocation, EERR_INCOMPATIBLE_OPERATOR, "Not a class or namespace");
|
||||
}
|
||||
|
||||
return dec;
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
}
|
||||
{
|
||||
Declaration* dec = ParseQualIdent();
|
||||
if (dec)
|
||||
{
|
||||
Declaration* pdec = mScope->Insert(dec->mIdent, dec);
|
||||
if (pdec && pdec != dec)
|
||||
mErrors->Error(dec->mLocation, EERR_DUPLICATE_DEFINITION, "Duplicate declaration", dec->mIdent);
|
||||
}
|
||||
|
||||
Declaration* bdec = ParseBaseTypeDeclaration(typeFlags);
|
||||
return dec;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
if (mScanner->mToken == TK_STATIC)
|
||||
{
|
||||
storageFlags |= DTF_STATIC;
|
||||
mScanner->NextToken();
|
||||
}
|
||||
else if (mScanner->mToken == TK_EXTERN)
|
||||
{
|
||||
storageFlags |= DTF_EXTERN;
|
||||
mScanner->NextToken();
|
||||
}
|
||||
else if (mScanner->mToken == TK_ZEROPAGE)
|
||||
{
|
||||
storageFlags |= DTF_ZEROPAGE;
|
||||
mScanner->NextToken();
|
||||
}
|
||||
else if (mScanner->mToken == TK_STRIPED)
|
||||
{
|
||||
storageFlags |= DTF_STRIPED;
|
||||
mScanner->NextToken();
|
||||
}
|
||||
else if (mScanner->mToken == TK_NOINLINE)
|
||||
{
|
||||
storageFlags |= DTF_PREVENT_INLINE;
|
||||
mScanner->NextToken();
|
||||
}
|
||||
else if (mScanner->mToken == TK_INLINE)
|
||||
{
|
||||
storageFlags |= DTF_REQUEST_INLINE;
|
||||
mScanner->NextToken();
|
||||
}
|
||||
else if (mScanner->mToken == TK_EXPORT)
|
||||
{
|
||||
storageFlags |= DTF_EXPORT;
|
||||
mScanner->NextToken();
|
||||
}
|
||||
else if (mScanner->mToken == TK_DYNSTACK)
|
||||
{
|
||||
storageFlags |= DTF_DYNSTACK;
|
||||
mScanner->NextToken();
|
||||
}
|
||||
else if (mScanner->mToken == TK_FASTCALL)
|
||||
{
|
||||
storageFlags |= DTF_FASTCALL;
|
||||
mScanner->NextToken();
|
||||
}
|
||||
else if (mScanner->mToken == TK_NATIVE)
|
||||
{
|
||||
storageFlags |= DTF_NATIVE;
|
||||
mScanner->NextToken();
|
||||
}
|
||||
else if (mScanner->mToken == TK_INTERRUPT)
|
||||
{
|
||||
storageFlags |= DTF_INTERRUPT | DTF_NATIVE;
|
||||
mScanner->NextToken();
|
||||
}
|
||||
else if (mScanner->mToken == TK_HWINTERRUPT)
|
||||
{
|
||||
storageFlags |= DTF_INTERRUPT | DTF_HWINTERRUPT | DTF_NATIVE;
|
||||
mScanner->NextToken();
|
||||
}
|
||||
else
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
bdec = ParseBaseTypeDeclaration(typeFlags);
|
||||
}
|
||||
|
||||
Declaration* rdec = nullptr, * ldec = nullptr;
|
||||
|
||||
|
@ -1155,9 +1199,9 @@ Declaration* Parser::ParseDeclaration(bool variable, bool expression)
|
|||
mErrors->Error(ndec->mLocation, ERRR_INVALID_STORAGE_TYPE, "Invalid storage type", ndec->mIdent);
|
||||
}
|
||||
|
||||
if (mGlobals == mScope && !(storageFlags & DTF_STATIC))
|
||||
if (mScope->mLevel < SLEVEL_FUNCTION && !(storageFlags & DTF_STATIC))
|
||||
{
|
||||
pdec = mCompilationUnits->mScope->Insert(ndec->mIdent, ndec);
|
||||
pdec = mCompilationUnits->mScope->Insert(ndec->mQualIdent, ndec);
|
||||
|
||||
Declaration * ldec = mScope->Insert(ndec->mIdent, pdec ? pdec : ndec);
|
||||
if (ldec && ldec != pdec)
|
||||
|
@ -1183,7 +1227,10 @@ Declaration* Parser::ParseDeclaration(bool variable, bool expression)
|
|||
while (npdec && ppdec)
|
||||
{
|
||||
if (npdec->mIdent)
|
||||
{
|
||||
ppdec->mIdent = npdec->mIdent;
|
||||
ppdec->mQualIdent = npdec->mQualIdent;
|
||||
}
|
||||
npdec = npdec->mNext;
|
||||
ppdec = ppdec->mNext;
|
||||
}
|
||||
|
@ -1236,7 +1283,7 @@ Declaration* Parser::ParseDeclaration(bool variable, bool expression)
|
|||
}
|
||||
}
|
||||
|
||||
if (mGlobals == mScope || (ndec->mFlags & DTF_STATIC))
|
||||
if (mScope->mLevel < SLEVEL_FUNCTION || (ndec->mFlags & DTF_STATIC))
|
||||
{
|
||||
ndec->mFlags |= DTF_GLOBAL;
|
||||
ndec->mVarIndex = -1;
|
||||
|
@ -1316,12 +1363,12 @@ Declaration* Parser::ParseDeclaration(bool variable, bool expression)
|
|||
return rdec;
|
||||
}
|
||||
|
||||
Expression* Parser::ParseDeclarationExpression(void)
|
||||
Expression* Parser::ParseDeclarationExpression(Declaration * pdec)
|
||||
{
|
||||
Declaration* dec;
|
||||
Expression* exp = nullptr, * rexp = nullptr;
|
||||
|
||||
dec = ParseDeclaration(true, true);
|
||||
dec = ParseDeclaration(pdec, true, true);
|
||||
if (dec->mType == DT_ANON && dec->mNext == 0)
|
||||
{
|
||||
exp = new Expression(dec->mLocation, EX_TYPE);
|
||||
|
@ -1366,6 +1413,44 @@ Expression* Parser::ParseDeclarationExpression(void)
|
|||
return exp;
|
||||
}
|
||||
|
||||
Declaration* Parser::ParseQualIdent(void)
|
||||
{
|
||||
Declaration* dec = mScope->Lookup(mScanner->mTokenIdent);
|
||||
if (dec)
|
||||
{
|
||||
mScanner->NextToken();
|
||||
while (ConsumeTokenIf(TK_COLCOLON))
|
||||
{
|
||||
if (mScanner->mToken == TK_IDENT)
|
||||
{
|
||||
if (dec->mType == DT_NAMESPACE)
|
||||
{
|
||||
Declaration* ndec = dec->mScope->Lookup(mScanner->mTokenIdent);
|
||||
|
||||
if (ndec)
|
||||
dec = ndec;
|
||||
else
|
||||
mErrors->Error(mScanner->mLocation, EERR_OBJECT_NOT_FOUND, "Unknown identifier", mScanner->mTokenIdent);
|
||||
}
|
||||
else
|
||||
mErrors->Error(mScanner->mLocation, EERR_INCOMPATIBLE_OPERATOR, "Not a class or namespace");
|
||||
|
||||
}
|
||||
else
|
||||
mErrors->Error(mScanner->mLocation, EERR_SYNTAX, "Identifier expected");
|
||||
|
||||
mScanner->NextToken();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
mErrors->Error(mScanner->mLocation, EERR_OBJECT_NOT_FOUND, "Unknown identifier", mScanner->mTokenIdent);
|
||||
mScanner->NextToken();
|
||||
}
|
||||
|
||||
return dec;
|
||||
}
|
||||
|
||||
Expression* Parser::ParseSimpleExpression(void)
|
||||
{
|
||||
Declaration* dec;
|
||||
|
@ -1390,7 +1475,7 @@ Expression* Parser::ParseSimpleExpression(void)
|
|||
case TK_STATIC:
|
||||
case TK_AUTO:
|
||||
case TK_STRIPED:
|
||||
exp = ParseDeclarationExpression();
|
||||
exp = ParseDeclarationExpression(nullptr);
|
||||
break;
|
||||
case TK_CHARACTER:
|
||||
dec = new Declaration(mScanner->mLocation, DT_CONST_INTEGER);
|
||||
|
@ -1538,7 +1623,7 @@ Expression* Parser::ParseSimpleExpression(void)
|
|||
mScanner->NextToken();
|
||||
break;
|
||||
case TK_IDENT:
|
||||
dec = mScope->Lookup(mScanner->mTokenIdent);
|
||||
dec = ParseQualIdent();
|
||||
if (dec)
|
||||
{
|
||||
if (dec->mType == DT_CONST_INTEGER || dec->mType == DT_CONST_FLOAT || dec->mType == DT_CONST_FUNCTION || dec->mType == DT_CONST_ASSEMBLER || dec->mType == DT_LABEL || dec->mType == DT_LABEL_REF)
|
||||
|
@ -1547,7 +1632,6 @@ Expression* Parser::ParseSimpleExpression(void)
|
|||
exp->mDecValue = dec;
|
||||
exp->mDecType = dec->mBase;
|
||||
exp->mConst = true;
|
||||
mScanner->NextToken();
|
||||
}
|
||||
else if (dec->mType == DT_VARIABLE || dec->mType == DT_ARGUMENT)
|
||||
{
|
||||
|
@ -1571,24 +1655,16 @@ Expression* Parser::ParseSimpleExpression(void)
|
|||
exp->mDecValue = dec;
|
||||
exp->mDecType = dec->mBase;
|
||||
}
|
||||
|
||||
mScanner->NextToken();
|
||||
}
|
||||
else if (dec->mType <= DT_TYPE_FUNCTION)
|
||||
{
|
||||
exp = ParseDeclarationExpression();
|
||||
exp = ParseDeclarationExpression(dec);
|
||||
}
|
||||
else
|
||||
{
|
||||
mErrors->Error(mScanner->mLocation, EERR_INVALID_IDENTIFIER, "Invalid identifier", mScanner->mTokenIdent);
|
||||
mScanner->NextToken();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
mErrors->Error(mScanner->mLocation, EERR_OBJECT_NOT_FOUND, "Unknown identifier", mScanner->mTokenIdent);
|
||||
mScanner->NextToken();
|
||||
}
|
||||
|
||||
break;
|
||||
case TK_SIZEOF:
|
||||
|
@ -2159,7 +2235,7 @@ Expression* Parser::ParseListExpression(void)
|
|||
|
||||
Expression* Parser::ParseFunction(Declaration * dec)
|
||||
{
|
||||
DeclarationScope* scope = new DeclarationScope(mScope);
|
||||
DeclarationScope* scope = new DeclarationScope(mScope, SLEVEL_FUNCTION);
|
||||
mScope = scope;
|
||||
|
||||
Declaration* pdec = dec->mParams;
|
||||
|
@ -2191,7 +2267,7 @@ Expression* Parser::ParseStatement(void)
|
|||
|
||||
if (mScanner->mToken == TK_OPEN_BRACE)
|
||||
{
|
||||
DeclarationScope* scope = new DeclarationScope(mScope);
|
||||
DeclarationScope* scope = new DeclarationScope(mScope, SLEVEL_LOCAL);
|
||||
mScope = scope;
|
||||
|
||||
mScanner->NextToken();
|
||||
|
@ -2256,7 +2332,7 @@ Expression* Parser::ParseStatement(void)
|
|||
{
|
||||
mScanner->NextToken();
|
||||
|
||||
DeclarationScope* scope = new DeclarationScope(mScope);
|
||||
DeclarationScope* scope = new DeclarationScope(mScope, SLEVEL_LOCAL);
|
||||
mScope = scope;
|
||||
|
||||
exp = new Expression(mScanner->mLocation, EX_WHILE);
|
||||
|
@ -2284,7 +2360,7 @@ Expression* Parser::ParseStatement(void)
|
|||
mScanner->NextToken();
|
||||
if (mScanner->mToken == TK_OPEN_PARENTHESIS)
|
||||
{
|
||||
DeclarationScope* scope = new DeclarationScope(mScope);
|
||||
DeclarationScope* scope = new DeclarationScope(mScope, SLEVEL_LOCAL);
|
||||
mScope = scope;
|
||||
|
||||
mScanner->NextToken();
|
||||
|
@ -2725,6 +2801,7 @@ Expression* Parser::ParseAssemblerBaseOperand(Declaration* pcasm, int pcoffset)
|
|||
exp = new Expression(mScanner->mLocation, EX_CONSTANT);
|
||||
dec = new Declaration(mScanner->mLocation, DT_LABEL);
|
||||
dec->mIdent = mScanner->mTokenIdent;
|
||||
dec->mQualIdent = mScanner->mTokenIdent;
|
||||
exp->mDecType = TheUnsignedIntTypeDeclaration;
|
||||
mScope->Insert(dec->mIdent, dec);
|
||||
}
|
||||
|
@ -2772,6 +2849,7 @@ Expression* Parser::ParseAssemblerBaseOperand(Declaration* pcasm, int pcoffset)
|
|||
{
|
||||
Declaration* ndec = new Declaration(mScanner->mLocation, DT_LABEL);
|
||||
ndec->mIdent = exp->mDecValue->mIdent;
|
||||
ndec->mQualIdent = exp->mDecValue->mQualIdent;
|
||||
ndec->mBase = exp->mDecValue;
|
||||
ndec->mInteger = 0;
|
||||
exp->mDecValue = ndec;
|
||||
|
@ -3017,6 +3095,7 @@ void Parser::AddAssemblerRegister(const Ident* ident, int value)
|
|||
{
|
||||
Declaration* decaccu = new Declaration(mScanner->mLocation, DT_CONST_INTEGER);
|
||||
decaccu->mIdent = ident;
|
||||
decaccu->mQualIdent = ident;
|
||||
decaccu->mBase = TheUnsignedIntTypeDeclaration;
|
||||
decaccu->mSize = 2;
|
||||
decaccu->mInteger = value;
|
||||
|
@ -3025,7 +3104,7 @@ void Parser::AddAssemblerRegister(const Ident* ident, int value)
|
|||
|
||||
Expression* Parser::ParseAssembler(void)
|
||||
{
|
||||
DeclarationScope* scope = new DeclarationScope(mScope);
|
||||
DeclarationScope* scope = new DeclarationScope(mScope, SLEVEL_LOCAL);
|
||||
mScope = scope;
|
||||
|
||||
mScanner->SetAssemblerMode(true);
|
||||
|
@ -3044,6 +3123,7 @@ Expression* Parser::ParseAssembler(void)
|
|||
|
||||
Declaration* decaccu = new Declaration(mScanner->mLocation, DT_CONST_INTEGER);
|
||||
decaccu->mIdent = Ident::Unique("accu");
|
||||
decaccu->mQualIdent = decaccu->mIdent;
|
||||
decaccu->mBase = TheUnsignedIntTypeDeclaration;
|
||||
decaccu->mSize = 2;
|
||||
decaccu->mInteger = BC_REG_ACCU;
|
||||
|
@ -3095,6 +3175,7 @@ Expression* Parser::ParseAssembler(void)
|
|||
dec = new Declaration(mScanner->mLocation, DT_LABEL);
|
||||
|
||||
dec->mIdent = label;
|
||||
dec->mQualIdent = dec->mIdent;
|
||||
dec->mValue = ilast;
|
||||
dec->mInteger = offset;
|
||||
dec->mBase = vdasm;
|
||||
|
@ -4105,6 +4186,84 @@ void Parser::ParsePragma(void)
|
|||
mErrors->Error(mScanner->mLocation, EERR_SYNTAX, "Invalid pragma directive");
|
||||
}
|
||||
|
||||
void Parser::ParseNamespace(void)
|
||||
{
|
||||
if (mScanner->mToken == TK_IDENT)
|
||||
{
|
||||
const Ident* ident = mScanner->mTokenIdent;
|
||||
|
||||
mScanner->NextToken();
|
||||
|
||||
if (mScanner->mToken == TK_OPEN_BRACE)
|
||||
{
|
||||
Declaration* ns = mScope->Lookup(ident);
|
||||
if (ns)
|
||||
{
|
||||
if (ns->mType != DT_NAMESPACE)
|
||||
{
|
||||
mErrors->Error(mScanner->mLocation, ERRO_NOT_A_NAMESPACE, "Not a namespace", ident);
|
||||
ns = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
if (!ns)
|
||||
{
|
||||
ns = new Declaration(mScanner->mLocation, DT_NAMESPACE);
|
||||
mScope->Insert(ident, ns);
|
||||
ns->mScope = new DeclarationScope(mScope, SLEVEL_NAMESPACE, ident);
|
||||
}
|
||||
|
||||
mScanner->NextToken();
|
||||
|
||||
DeclarationScope* outerScope = mScope;
|
||||
mScope = ns->mScope;
|
||||
|
||||
while (mScanner->mToken != TK_EOF && mScanner->mToken != TK_CLOSE_BRACE)
|
||||
{
|
||||
if (mScanner->mToken == TK_PREP_PRAGMA)
|
||||
{
|
||||
mScanner->NextToken();
|
||||
ParsePragma();
|
||||
}
|
||||
else if (mScanner->mToken == TK_SEMICOLON)
|
||||
mScanner->NextToken();
|
||||
else if (mScanner->mToken == TK_NAMESPACE)
|
||||
{
|
||||
mScanner->NextToken();
|
||||
ParseNamespace();
|
||||
}
|
||||
else
|
||||
ParseDeclaration(nullptr, true, false);
|
||||
}
|
||||
|
||||
ConsumeToken(TK_CLOSE_BRACE);
|
||||
|
||||
mScope = outerScope;
|
||||
}
|
||||
else
|
||||
{
|
||||
ConsumeToken(TK_ASSIGN);
|
||||
Declaration* dec = ParseQualIdent();
|
||||
if (dec)
|
||||
{
|
||||
if (dec->mType == DT_NAMESPACE)
|
||||
{
|
||||
Declaration* ns = mScope->Insert(ident, dec);
|
||||
if (ns)
|
||||
mErrors->Error(mScanner->mLocation, EERR_DUPLICATE_DEFINITION, "Duplicate definition", ident);
|
||||
}
|
||||
else
|
||||
mErrors->Error(mScanner->mLocation, ERRO_NOT_A_NAMESPACE, "Not a namespace", ident);
|
||||
}
|
||||
ConsumeToken(TK_SEMICOLON);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Annonymous namespace
|
||||
}
|
||||
}
|
||||
|
||||
void Parser::Parse(void)
|
||||
{
|
||||
mLocalIndex = 0;
|
||||
|
@ -4144,7 +4303,12 @@ void Parser::Parse(void)
|
|||
}
|
||||
else if (mScanner->mToken == TK_SEMICOLON)
|
||||
mScanner->NextToken();
|
||||
else if (mScanner->mToken == TK_NAMESPACE)
|
||||
{
|
||||
mScanner->NextToken();
|
||||
ParseNamespace();
|
||||
}
|
||||
else
|
||||
ParseDeclaration(true, false);
|
||||
ParseDeclaration(nullptr, true, false);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,6 +13,7 @@ public:
|
|||
DeclarationScope * mGlobals, * mScope;
|
||||
int mLocalIndex;
|
||||
CompilationUnits * mCompilationUnits;
|
||||
Declaration * mNamespace;
|
||||
|
||||
LinkerSection * mCodeSection, * mDataSection, * mBSSection;
|
||||
|
||||
|
@ -33,15 +34,17 @@ protected:
|
|||
|
||||
uint8* ParseStringLiteral(int msize);
|
||||
|
||||
void ParseNamespace(void);
|
||||
|
||||
void ParsePragma(void);
|
||||
|
||||
Declaration* ParseBaseTypeDeclaration(uint64 flags);
|
||||
Declaration* ParseDeclaration(bool variable, bool expression);
|
||||
Declaration* ParseDeclaration(Declaration* pdec, bool variable, bool expression);
|
||||
Declaration* ParseStructDeclaration(uint64 flags, DecType dt);
|
||||
|
||||
Declaration* CopyConstantInitializer(int offset, Declaration* dtype, Expression* exp);
|
||||
Expression* ParseInitExpression(Declaration* dtype);
|
||||
Expression* ParseDeclarationExpression(void);
|
||||
Expression* ParseDeclarationExpression(Declaration* pdec);
|
||||
|
||||
Declaration* ParsePostfixDeclaration(void);
|
||||
Declaration* ReverseDeclaration(Declaration* odec, Declaration* bdec);
|
||||
|
@ -56,6 +59,8 @@ protected:
|
|||
|
||||
void AddAssemblerRegister(const Ident* ident, int value);
|
||||
|
||||
Declaration* ParseQualIdent(void);
|
||||
|
||||
Expression* ParseStatement(void);
|
||||
Expression* ParseSwitchStatement(void);
|
||||
|
||||
|
|
|
@ -148,7 +148,11 @@ const char* TokenNames[] =
|
|||
"'#repeat'",
|
||||
"'#until'",
|
||||
"'#embed'",
|
||||
"'##'"
|
||||
"'##'",
|
||||
|
||||
"'namespace'",
|
||||
"'using'",
|
||||
"'::'"
|
||||
};
|
||||
|
||||
|
||||
|
@ -311,7 +315,6 @@ Scanner::Scanner(Errors* errors, Preprocessor* preprocessor)
|
|||
mToken = TK_NONE;
|
||||
|
||||
NextChar();
|
||||
NextToken();
|
||||
|
||||
assert(sizeof(TokenNames) == NUM_TOKENS * sizeof(char*));
|
||||
}
|
||||
|
@ -1088,6 +1091,11 @@ void Scanner::NextRawToken(void)
|
|||
case ':':
|
||||
mToken = TK_COLON;
|
||||
NextChar();
|
||||
if (mTokenChar == ':' && (mCompilerOptions & COPT_CPLUSPLUS))
|
||||
{
|
||||
mToken = TK_COLCOLON;
|
||||
NextChar();
|
||||
}
|
||||
break;
|
||||
case '?':
|
||||
mToken = TK_QUESTIONMARK;
|
||||
|
@ -1379,6 +1387,10 @@ void Scanner::NextRawToken(void)
|
|||
mToken = TK_STRIPED;
|
||||
else if (!strcmp(tkident, "__dynstack"))
|
||||
mToken = TK_DYNSTACK;
|
||||
else if ((mCompilerOptions & COPT_CPLUSPLUS) && !strcmp(tkident, "namespace"))
|
||||
mToken = TK_NAMESPACE;
|
||||
else if ((mCompilerOptions & COPT_CPLUSPLUS) && !strcmp(tkident, "using"))
|
||||
mToken = TK_USING;
|
||||
else
|
||||
{
|
||||
mToken = TK_IDENT;
|
||||
|
|
|
@ -149,6 +149,10 @@ enum Token
|
|||
|
||||
TK_PREP_CONCAT,
|
||||
|
||||
TK_NAMESPACE,
|
||||
TK_USING,
|
||||
TK_COLCOLON,
|
||||
|
||||
NUM_TOKENS
|
||||
};
|
||||
|
||||
|
@ -231,6 +235,8 @@ public:
|
|||
bool mAssemblerMode;
|
||||
bool mPreprocessorMode;
|
||||
|
||||
uint64 mCompilerOptions;
|
||||
|
||||
void AddMacro(const Ident* ident, const char* value);
|
||||
protected:
|
||||
void NextRawToken(void);
|
||||
|
|
|
@ -237,6 +237,11 @@ int main2(int argc, const char** argv)
|
|||
{
|
||||
compiler->mCompilerOptions |= COPT_EXTENDED_ZERO_PAGE;
|
||||
}
|
||||
else if (arg[1] == 'p' && arg[2] == 'p')
|
||||
{
|
||||
compiler->mCompilerOptions |= COPT_CPLUSPLUS;
|
||||
compiler->AddDefine(Ident::Unique("__cplusplus"), "1");
|
||||
}
|
||||
else
|
||||
compiler->mErrors->Error(loc, EERR_COMMAND_LINE, "Invalid command line argument", arg);
|
||||
}
|
||||
|
@ -244,6 +249,14 @@ int main2(int argc, const char** argv)
|
|||
{
|
||||
if (!targetPath[0])
|
||||
strcpy_s(targetPath, argv[i]);
|
||||
|
||||
int n = strlen(argv[i]);
|
||||
if (n > 4 && argv[i][n - 4] == '.' && argv[i][n - 3] == 'c' && argv[i][n - 2] == 'p' && argv[i][n - 1] == 'p')
|
||||
{
|
||||
compiler->mCompilerOptions |= COPT_CPLUSPLUS;
|
||||
compiler->AddDefine(Ident::Unique("__cplusplus"), "1");
|
||||
}
|
||||
|
||||
compiler->mCompilationUnits->AddUnit(loc, argv[i], nullptr);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue