Add .cpp mode and namespace/using

This commit is contained in:
drmortalwombat 2023-06-17 15:08:03 +02:00
parent 433270f90f
commit fd391690b9
13 changed files with 395 additions and 135 deletions

View File

@ -12,8 +12,8 @@ CompilationUnits::CompilationUnits(Errors * errors)
{ {
mCompilationUnits = nullptr; mCompilationUnits = nullptr;
mPendingUnits = nullptr; mPendingUnits = nullptr;
mScope = new DeclarationScope(nullptr); mScope = new DeclarationScope(nullptr, SLEVEL_GLOBAL);
mRuntimeScope = new DeclarationScope(nullptr); mRuntimeScope = new DeclarationScope(nullptr, SLEVEL_GLOBAL);
mStartup = nullptr; mStartup = nullptr;
for (int i = 0; i < 256; i++) for (int i = 0; i < 256; i++)

View File

@ -145,6 +145,10 @@ bool Compiler::ParseSource(void)
for (int i = 0; i < mDefines.Size(); i++) for (int i = 0; i < mDefines.Size(); i++)
scanner->AddMacro(mDefines[i].mIdent, mDefines[i].mValue); scanner->AddMacro(mDefines[i].mIdent, mDefines[i].mValue);
scanner->mCompilerOptions = mCompilerOptions;
scanner->NextToken();
Parser* parser = new Parser(mErrors, scanner, mCompilationUnits); Parser* parser = new Parser(mErrors, scanner, mCompilationUnits);
parser->mCompilerOptions = mCompilerOptions; parser->mCompilerOptions = mCompilerOptions;
@ -1161,25 +1165,25 @@ bool Compiler::WriteDbjFile(const char* filename)
{ {
case DT_TYPE_INTEGER: case DT_TYPE_INTEGER:
if (dec->mFlags & DTF_SIGNED) 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 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; break;
case DT_TYPE_FLOAT: 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; break;
case DT_TYPE_BOOL: 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; break;
case DT_TYPE_ARRAY: 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; break;
case DT_TYPE_POINTER: 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; break;
case DT_TYPE_ENUM: 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; bool tfirst = true;
Declaration* mdec = dec->mParams; Declaration* mdec = dec->mParams;
while (mdec) while (mdec)
@ -1201,7 +1205,7 @@ bool Compiler::WriteDbjFile(const char* filename)
break; break;
case DT_TYPE_STRUCT: 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; bool tfirst = true;
Declaration* mdec = dec->mParams; Declaration* mdec = dec->mParams;
while (mdec) while (mdec)
@ -1218,7 +1222,7 @@ bool Compiler::WriteDbjFile(const char* filename)
} }
break; break;
default: 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);
} }
} }

View File

@ -34,6 +34,9 @@ static const uint64 COPT_VERBOSE3 = 1ULL << 50;
static const uint64 COPT_DEBUGINFO = 1ULL << 51; 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; static const uint64 COPT_DEFAULT = COPT_OPTIMIZE_BASIC | COPT_OPTIMIZE_INLINE | COPT_OPTIMIZE_CONST_EXPRESSIONS;

View File

@ -1,8 +1,10 @@
#include "Declaration.h" #include "Declaration.h"
DeclarationScope::DeclarationScope(DeclarationScope* parent) DeclarationScope::DeclarationScope(DeclarationScope* parent, ScopeLevel level, const Ident* name)
{ {
mParent = parent; mParent = parent;
mLevel = level;
mName = name;
mHashSize = 0; mHashSize = 0;
mHashFill = 0; mHashFill = 0;
mHash = nullptr; mHash = nullptr;
@ -13,6 +15,25 @@ DeclarationScope::~DeclarationScope(void)
delete[] mHash; 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) Declaration * DeclarationScope::Insert(const Ident* ident, Declaration* dec)
{ {
if (!mHash) 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; return mParent ? mParent->Lookup(ident) : nullptr;
} }
@ -602,7 +630,8 @@ Expression* Expression::ConstantFold(Errors * errors)
} }
Declaration::Declaration(const Location& loc, DecType type) 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), mBase(nullptr), mParams(nullptr), mValue(nullptr), mNext(nullptr), mConst(nullptr),
mVarIndex(-1), mLinkerObject(nullptr), mCallers(nullptr), mCalled(nullptr), mAlignment(1), 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), 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->mScope = mScope;
ndec->mParams = mParams; ndec->mParams = mParams;
ndec->mIdent = mIdent; ndec->mIdent = mIdent;
ndec->mQualIdent = mQualIdent;
ndec->mValue = mValue; ndec->mValue = mValue;
ndec->mVarIndex = mVarIndex; ndec->mVarIndex = mVarIndex;
ndec->mLinkerObject = mLinkerObject; ndec->mLinkerObject = mLinkerObject;
@ -689,6 +719,7 @@ Declaration* Declaration::ToStriped(int stripe)
ndec->mStripe = stripe; ndec->mStripe = stripe;
ndec->mFlags = mFlags; ndec->mFlags = mFlags;
ndec->mIdent = mIdent; ndec->mIdent = mIdent;
ndec->mQualIdent = mQualIdent;
if (mType == DT_ELEMENT) if (mType == DT_ELEMENT)
ndec->mBase = mBase->ToStriped(stripe); ndec->mBase = mBase->ToStriped(stripe);
@ -697,7 +728,7 @@ Declaration* Declaration::ToStriped(int stripe)
if (mType == DT_TYPE_STRUCT) if (mType == DT_TYPE_STRUCT)
{ {
ndec->mScope = new DeclarationScope(nullptr); ndec->mScope = new DeclarationScope(nullptr, mScope->mLevel);
Declaration * p = mParams; Declaration * p = mParams;
Declaration* prev = nullptr; Declaration* prev = nullptr;
while (p) while (p)
@ -743,6 +774,7 @@ Declaration* Declaration::ToConstType(void)
ndec->mScope = mScope; ndec->mScope = mScope;
ndec->mParams = mParams; ndec->mParams = mParams;
ndec->mIdent = mIdent; ndec->mIdent = mIdent;
ndec->mQualIdent = mQualIdent;
mConst = ndec; mConst = ndec;
} }

View File

@ -45,7 +45,8 @@ enum DecType
DT_LABEL, DT_LABEL,
DT_VARIABLE_REF, DT_VARIABLE_REF,
DT_FUNCTION_REF, DT_FUNCTION_REF,
DT_LABEL_REF DT_LABEL_REF,
DT_NAMESPACE,
}; };
// TypeFlags // TypeFlags
@ -96,17 +97,34 @@ static const uint64 DTF_VAR_ALIASING = (1ULL << 48);
class Declaration; class Declaration;
enum ScopeLevel
{
SLEVEL_GLOBAL,
SLEVEL_STATIC,
SLEVEL_NAMESPACE,
SLEVEL_CLASS,
SLEVEL_FUNCTION,
SLEVEL_LOCAL
};
class DeclarationScope class DeclarationScope
{ {
public: public:
DeclarationScope(DeclarationScope * parent); DeclarationScope(DeclarationScope * parent, ScopeLevel level, const Ident * name = nullptr);
~DeclarationScope(void); ~DeclarationScope(void);
const Ident* Mangle(const Ident* ident) const;
Declaration* Insert(const Ident* ident, Declaration* dec); Declaration* Insert(const Ident* ident, Declaration* dec);
Declaration* Lookup(const Ident* ident); Declaration* Lookup(const Ident* ident);
void End(const Location & loc); void End(const Location & loc);
void UseScope(DeclarationScope* scope);
ScopeLevel mLevel;
const Ident * mName;
DeclarationScope* mParent; DeclarationScope* mParent;
protected: protected:
struct Entry struct Entry
@ -116,6 +134,7 @@ protected:
}; };
Entry * mHash; Entry * mHash;
int mHashSize, mHashFill; int mHashSize, mHashFill;
ExpandingArray<DeclarationScope*> mUsed;
}; };
enum ExpressionType enum ExpressionType
@ -199,7 +218,7 @@ public:
int64 mInteger, mMinValue, mMaxValue; int64 mInteger, mMinValue, mMaxValue;
double mNumber; double mNumber;
uint64 mFlags, mCompilerOptions; uint64 mFlags, mCompilerOptions;
const Ident * mIdent; const Ident * mIdent, * mQualIdent;
LinkerSection * mSection; LinkerSection * mSection;
const uint8 * mData; const uint8 * mData;
LinkerObject * mLinkerObject; LinkerObject * mLinkerObject;

View File

@ -69,6 +69,7 @@ enum ErrorID
ERRR_USE_OF_UNINITIALIZED_VARIABLE, ERRR_USE_OF_UNINITIALIZED_VARIABLE,
ERRR_STRIPE_REQUIRES_FIXED_SIZE_ARRAY, ERRR_STRIPE_REQUIRES_FIXED_SIZE_ARRAY,
ERRR_CANNOT_FIND_BANK_OF_EXPRESSION, ERRR_CANNOT_FIND_BANK_OF_EXPRESSION,
ERRO_NOT_A_NAMESPACE,
ERRR_STACK_OVERFLOW, ERRR_STACK_OVERFLOW,
ERRR_INVALID_NUMBER, ERRR_INVALID_NUMBER,

View File

@ -40,21 +40,21 @@ void GlobalAnalyzer::DumpCallGraph(void)
for (int j = 0; j < decs.Size(); j++) for (int j = 0; j < decs.Size(); j++)
{ {
if (decs[j]->mType == DT_CONST_FUNCTION) 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 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 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++) for (int i = 0; i < mGlobalVariables.Size(); i++)
{ {
Declaration* var = mGlobalVariables[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); Analyze(exp, dec, false);
} }
else 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; dec->mFlags &= ~DTF_FUNC_ANALYZING;
} }
@ -662,7 +662,7 @@ Declaration * GlobalAnalyzer::Analyze(Expression* exp, Declaration* procDec, boo
{ {
procDec->mFlags &= ~DTF_FUNC_INTRSAVE; procDec->mFlags &= ~DTF_FUNC_INTRSAVE;
if (procDec->mFlags & DTF_INTERRUPT) 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)) if (!(GetProcFlags(ldec) & DTF_FUNC_PURE))
procDec->mFlags &= ~DTF_FUNC_PURE; procDec->mFlags &= ~DTF_FUNC_PURE;

View File

@ -376,8 +376,8 @@ void InterCodeGenerator::InitGlobalVariable(InterCodeModule * mod, Declaration*
InterVariable * var = new InterVariable(); InterVariable * var = new InterVariable();
var->mOffset = 0; var->mOffset = 0;
var->mSize = dec->mSize; var->mSize = dec->mSize;
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);
var->mIdent = dec->mIdent; var->mIdent = dec->mQualIdent;
Declaration* decb = dec->mBase; Declaration* decb = dec->mBase;
while (decb && decb->mType == DT_TYPE_ARRAY) while (decb && decb->mType == DT_TYPE_ARRAY)
@ -437,7 +437,7 @@ void InterCodeGenerator::TranslateAssembler(InterCodeModule* mod, Expression* ex
Declaration* dec = exp->mDecValue; 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); uint8* d = dec->mLinkerObject->AddSpace(osize);
@ -485,7 +485,7 @@ void InterCodeGenerator::TranslateAssembler(InterCodeModule* mod, Expression* ex
dec->mLinkerObject->AddReference(ref); dec->mLinkerObject->AddReference(ref);
} }
else 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) else if (aexp->mType == DT_VARIABLE_REF)
{ {
@ -730,7 +730,7 @@ void InterCodeGenerator::TranslateAssembler(InterCodeModule* mod, Expression* ex
if (aexp->mBase->mBase) if (aexp->mBase->mBase)
d[offset] = uint8(aexp->mOffset + aexp->mBase->mInteger - offset - 1); d[offset] = uint8(aexp->mOffset + aexp->mBase->mInteger - offset - 1);
else 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 else
d[offset] = uint8(aexp->mInteger - offset - 1); d[offset] = uint8(aexp->mInteger - offset - 1);
@ -884,6 +884,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateInline(Declaration* pro
ains->mConst.mOperandSize = pdec->mSize; ains->mConst.mOperandSize = pdec->mSize;
vdec->mSize = ains->mConst.mOperandSize; vdec->mSize = ains->mConst.mOperandSize;
vdec->mIdent = pdec->mIdent; vdec->mIdent = pdec->mIdent;
vdec->mQualIdent = pdec->mQualIdent;
} }
else else
{ {
@ -1177,12 +1178,12 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
dec->mVarIndex = proc->mModule->mGlobalVars.Size(); dec->mVarIndex = proc->mModule->mGlobalVars.Size();
InterVariable* var = new InterVariable(); InterVariable* var = new InterVariable();
var->mIndex = dec->mVarIndex; var->mIndex = dec->mVarIndex;
var->mIdent = dec->mIdent; var->mIdent = dec->mQualIdent;
var->mOffset = 0; var->mOffset = 0;
var->mSize = dec->mSize; var->mSize = dec->mSize;
if ((dec->mFlags & DTF_VAR_ALIASING) || dec->mBase->mType == DT_TYPE_ARRAY) if ((dec->mFlags & DTF_VAR_ALIASING) || dec->mBase->mType == DT_TYPE_ARRAY)
var->mAliased = true; 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; dec->mLinkerObject = var->mLinkerObject;
var->mLinkerObject->AddData(dec->mData, dec->mSize); var->mLinkerObject->AddData(dec->mData, dec->mSize);
proc->mModule->mGlobalVars.Push(var); proc->mModule->mGlobalVars.Push(var);
@ -1209,9 +1210,9 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
var->mSize = dec->mSize; var->mSize = dec->mSize;
if (dec->mFlags & DTF_VAR_ALIASING) if (dec->mFlags & DTF_VAR_ALIASING)
var->mAliased = true; 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; dec->mLinkerObject = var->mLinkerObject;
var->mIdent = dec->mIdent; var->mIdent = dec->mQualIdent;
dec->mVarIndex = proc->mModule->mGlobalVars.Size(); dec->mVarIndex = proc->mModule->mGlobalVars.Size();
var->mIndex = dec->mVarIndex; var->mIndex = dec->mVarIndex;
proc->mModule->mGlobalVars.Push(var); 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)) if (exp->mLeft->mType == EX_CONSTANT && exp->mLeft->mDecValue->mType == DT_CONST_FUNCTION && (exp->mLeft->mDecValue->mFlags & DTF_INTRINSIC))
{ {
Declaration* decf = exp->mLeft->mDecValue; Declaration* decf = exp->mLeft->mDecValue;
const Ident * iname = decf->mIdent; const Ident * iname = decf->mQualIdent;
if (!strcmp(iname->mString, "fabs")) if (!strcmp(iname->mString, "fabs"))
{ {
@ -3657,7 +3658,7 @@ void InterCodeGenerator::BuildInitializer(InterCodeModule * mod, uint8* dp, int
var->mSize = dec->mSize; var->mSize = dec->mSize;
if (dec->mFlags & DTF_VAR_ALIASING) if (dec->mFlags & DTF_VAR_ALIASING)
var->mAliased = true; 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; dec->mLinkerObject = var->mLinkerObject;
var->mLinkerObject->AddData(dec->mData, dec->mSize); var->mLinkerObject->AddData(dec->mData, dec->mSize);
mod->mGlobalVars.Push(var); mod->mGlobalVars.Push(var);
@ -3756,7 +3757,7 @@ void InterCodeGenerator::TranslateLogic(Declaration* procType, InterCodeProcedur
InterCodeProcedure* InterCodeGenerator::TranslateProcedure(InterCodeModule * mod, Expression* exp, Declaration * dec) 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; uint64 outerCompilerOptions = mCompilerOptions;
mCompilerOptions = dec->mCompilerOptions; mCompilerOptions = dec->mCompilerOptions;
@ -3845,7 +3846,7 @@ InterCodeProcedure* InterCodeGenerator::TranslateProcedure(InterCodeModule * mod
TranslateExpression(dec->mBase, proc, exitBlock, exp, nullptr, nullptr, nullptr); TranslateExpression(dec->mBase, proc, exitBlock, exp, nullptr, nullptr, nullptr);
} }
else 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); InterInstruction * ins = new InterInstruction(exp ? exp->mEndLocation : dec->mLocation, IC_RETURN);
exitBlock->Append(ins); exitBlock->Append(ins);

View File

@ -6,7 +6,7 @@
Parser::Parser(Errors* errors, Scanner* scanner, CompilationUnits* compilationUnits) Parser::Parser(Errors* errors, Scanner* scanner, CompilationUnits* compilationUnits)
: mErrors(errors), mScanner(scanner), mCompilationUnits(compilationUnits) : mErrors(errors), mScanner(scanner), mCompilationUnits(compilationUnits)
{ {
mGlobals = new DeclarationScope(compilationUnits->mScope); mGlobals = new DeclarationScope(compilationUnits->mScope, SLEVEL_STATIC);
mScope = mGlobals; mScope = mGlobals;
mCodeSection = compilationUnits->mSectionCode; mCodeSection = compilationUnits->mSectionCode;
@ -63,7 +63,8 @@ Declaration* Parser::ParseStructDeclaration(uint64 flags, DecType dt)
if (!dec->mIdent || !dec->mScope) if (!dec->mIdent || !dec->mScope)
{ {
dec->mIdent = structName; 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) if (mScanner->mToken == TK_OPEN_BRACE)
@ -72,7 +73,7 @@ Declaration* Parser::ParseStructDeclaration(uint64 flags, DecType dt)
Declaration* mlast = nullptr; Declaration* mlast = nullptr;
for (;;) for (;;)
{ {
Declaration* mdec = ParseDeclaration(false, false); Declaration* mdec = ParseDeclaration(nullptr, false, false);
int offset = dec->mSize; int offset = dec->mSize;
if (dt == DT_TYPE_UNION) if (dt == DT_TYPE_UNION)
@ -265,6 +266,7 @@ Declaration* Parser::ParseBaseTypeDeclaration(uint64 flags)
ndec->mScope = dec->mScope; ndec->mScope = dec->mScope;
ndec->mParams = dec->mParams; ndec->mParams = dec->mParams;
ndec->mIdent = dec->mIdent; ndec->mIdent = dec->mIdent;
ndec->mQualIdent = dec->mQualIdent;
dec = ndec; dec = ndec;
} }
mScanner->NextToken(); mScanner->NextToken();
@ -286,12 +288,13 @@ Declaration* Parser::ParseBaseTypeDeclaration(uint64 flags)
dec = new Declaration(mScanner->mLocation, DT_TYPE_ENUM); dec = new Declaration(mScanner->mLocation, DT_TYPE_ENUM);
dec->mFlags = flags; dec->mFlags = flags;
dec->mSize = 1; dec->mSize = 1;
dec->mScope = new DeclarationScope(nullptr); dec->mScope = new DeclarationScope(nullptr, SLEVEL_CLASS);
mScanner->NextToken(); mScanner->NextToken();
if (mScanner->mToken == TK_IDENT) if (mScanner->mToken == TK_IDENT)
{ {
dec->mIdent = mScanner->mTokenIdent; dec->mIdent = mScanner->mTokenIdent;
dec->mQualIdent = mScope->Mangle(dec->mIdent);
if (mScope->Insert(dec->mIdent, dec)) if (mScope->Insert(dec->mIdent, dec))
mErrors->Error(dec->mLocation, EERR_DUPLICATE_DEFINITION, "Duplicate name", dec->mIdent); 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) if (mScanner->mToken == TK_IDENT)
{ {
cdec->mIdent = mScanner->mTokenIdent; cdec->mIdent = mScanner->mTokenIdent;
cdec->mQualIdent = mScope->Mangle(cdec->mIdent);
if (mScope->Insert(cdec->mIdent, cdec) != nullptr) if (mScope->Insert(cdec->mIdent, cdec) != nullptr)
mErrors->Error(mScanner->mLocation, EERR_DUPLICATE_DEFINITION, "Duplicate declaration", mScanner->mTokenIdent->mString); mErrors->Error(mScanner->mLocation, EERR_DUPLICATE_DEFINITION, "Duplicate declaration", mScanner->mTokenIdent->mString);
mScanner->NextToken(); mScanner->NextToken();
@ -441,6 +445,7 @@ Declaration* Parser::ParsePostfixDeclaration(void)
{ {
dec = new Declaration(mScanner->mLocation, DT_VARIABLE); dec = new Declaration(mScanner->mLocation, DT_VARIABLE);
dec->mIdent = mScanner->mTokenIdent; dec->mIdent = mScanner->mTokenIdent;
dec->mQualIdent = mScope->Mangle(dec->mIdent);
dec->mSection = mBSSection; dec->mSection = mBSSection;
dec->mBase = nullptr; dec->mBase = nullptr;
mScanner->NextToken(); mScanner->NextToken();
@ -1005,17 +1010,55 @@ Expression* Parser::ParseInitExpression(Declaration* dtype)
return exp; return exp;
} }
Declaration* Parser::ParseDeclaration(bool variable, bool expression) Declaration* Parser::ParseDeclaration(Declaration * pdec, bool variable, bool expression)
{ {
bool definingType = false; bool definingType = false;
uint64 storageFlags = 0, typeFlags = 0; uint64 storageFlags = 0, typeFlags = 0;
Declaration* bdec;
if (pdec)
{
bdec = pdec;
}
else
{
if (mScanner->mToken == TK_TYPEDEF) if (mScanner->mToken == TK_TYPEDEF)
{ {
definingType = true; definingType = true;
variable = false; variable = false;
mScanner->NextToken(); mScanner->NextToken();
} }
else if (mScanner->mToken == TK_USING)
{
mScanner->NextToken();
if (ConsumeTokenIf(TK_NAMESPACE))
{
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
{
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);
}
return dec;
}
}
else else
{ {
for (;;) for (;;)
@ -1085,7 +1128,8 @@ Declaration* Parser::ParseDeclaration(bool variable, bool expression)
} }
} }
Declaration* bdec = ParseBaseTypeDeclaration(typeFlags); bdec = ParseBaseTypeDeclaration(typeFlags);
}
Declaration* rdec = nullptr, * ldec = nullptr; 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); 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); Declaration * ldec = mScope->Insert(ndec->mIdent, pdec ? pdec : ndec);
if (ldec && ldec != pdec) if (ldec && ldec != pdec)
@ -1183,7 +1227,10 @@ Declaration* Parser::ParseDeclaration(bool variable, bool expression)
while (npdec && ppdec) while (npdec && ppdec)
{ {
if (npdec->mIdent) if (npdec->mIdent)
{
ppdec->mIdent = npdec->mIdent; ppdec->mIdent = npdec->mIdent;
ppdec->mQualIdent = npdec->mQualIdent;
}
npdec = npdec->mNext; npdec = npdec->mNext;
ppdec = ppdec->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->mFlags |= DTF_GLOBAL;
ndec->mVarIndex = -1; ndec->mVarIndex = -1;
@ -1316,12 +1363,12 @@ Declaration* Parser::ParseDeclaration(bool variable, bool expression)
return rdec; return rdec;
} }
Expression* Parser::ParseDeclarationExpression(void) Expression* Parser::ParseDeclarationExpression(Declaration * pdec)
{ {
Declaration* dec; Declaration* dec;
Expression* exp = nullptr, * rexp = nullptr; Expression* exp = nullptr, * rexp = nullptr;
dec = ParseDeclaration(true, true); dec = ParseDeclaration(pdec, true, true);
if (dec->mType == DT_ANON && dec->mNext == 0) if (dec->mType == DT_ANON && dec->mNext == 0)
{ {
exp = new Expression(dec->mLocation, EX_TYPE); exp = new Expression(dec->mLocation, EX_TYPE);
@ -1366,6 +1413,44 @@ Expression* Parser::ParseDeclarationExpression(void)
return exp; 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) Expression* Parser::ParseSimpleExpression(void)
{ {
Declaration* dec; Declaration* dec;
@ -1390,7 +1475,7 @@ Expression* Parser::ParseSimpleExpression(void)
case TK_STATIC: case TK_STATIC:
case TK_AUTO: case TK_AUTO:
case TK_STRIPED: case TK_STRIPED:
exp = ParseDeclarationExpression(); exp = ParseDeclarationExpression(nullptr);
break; break;
case TK_CHARACTER: case TK_CHARACTER:
dec = new Declaration(mScanner->mLocation, DT_CONST_INTEGER); dec = new Declaration(mScanner->mLocation, DT_CONST_INTEGER);
@ -1538,7 +1623,7 @@ Expression* Parser::ParseSimpleExpression(void)
mScanner->NextToken(); mScanner->NextToken();
break; break;
case TK_IDENT: case TK_IDENT:
dec = mScope->Lookup(mScanner->mTokenIdent); dec = ParseQualIdent();
if (dec) 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) 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->mDecValue = dec;
exp->mDecType = dec->mBase; exp->mDecType = dec->mBase;
exp->mConst = true; exp->mConst = true;
mScanner->NextToken();
} }
else if (dec->mType == DT_VARIABLE || dec->mType == DT_ARGUMENT) else if (dec->mType == DT_VARIABLE || dec->mType == DT_ARGUMENT)
{ {
@ -1571,24 +1655,16 @@ Expression* Parser::ParseSimpleExpression(void)
exp->mDecValue = dec; exp->mDecValue = dec;
exp->mDecType = dec->mBase; exp->mDecType = dec->mBase;
} }
mScanner->NextToken();
} }
else if (dec->mType <= DT_TYPE_FUNCTION) else if (dec->mType <= DT_TYPE_FUNCTION)
{ {
exp = ParseDeclarationExpression(); exp = ParseDeclarationExpression(dec);
} }
else else
{ {
mErrors->Error(mScanner->mLocation, EERR_INVALID_IDENTIFIER, "Invalid identifier", mScanner->mTokenIdent); 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; break;
case TK_SIZEOF: case TK_SIZEOF:
@ -2159,7 +2235,7 @@ Expression* Parser::ParseListExpression(void)
Expression* Parser::ParseFunction(Declaration * dec) Expression* Parser::ParseFunction(Declaration * dec)
{ {
DeclarationScope* scope = new DeclarationScope(mScope); DeclarationScope* scope = new DeclarationScope(mScope, SLEVEL_FUNCTION);
mScope = scope; mScope = scope;
Declaration* pdec = dec->mParams; Declaration* pdec = dec->mParams;
@ -2191,7 +2267,7 @@ Expression* Parser::ParseStatement(void)
if (mScanner->mToken == TK_OPEN_BRACE) if (mScanner->mToken == TK_OPEN_BRACE)
{ {
DeclarationScope* scope = new DeclarationScope(mScope); DeclarationScope* scope = new DeclarationScope(mScope, SLEVEL_LOCAL);
mScope = scope; mScope = scope;
mScanner->NextToken(); mScanner->NextToken();
@ -2256,7 +2332,7 @@ Expression* Parser::ParseStatement(void)
{ {
mScanner->NextToken(); mScanner->NextToken();
DeclarationScope* scope = new DeclarationScope(mScope); DeclarationScope* scope = new DeclarationScope(mScope, SLEVEL_LOCAL);
mScope = scope; mScope = scope;
exp = new Expression(mScanner->mLocation, EX_WHILE); exp = new Expression(mScanner->mLocation, EX_WHILE);
@ -2284,7 +2360,7 @@ Expression* Parser::ParseStatement(void)
mScanner->NextToken(); mScanner->NextToken();
if (mScanner->mToken == TK_OPEN_PARENTHESIS) if (mScanner->mToken == TK_OPEN_PARENTHESIS)
{ {
DeclarationScope* scope = new DeclarationScope(mScope); DeclarationScope* scope = new DeclarationScope(mScope, SLEVEL_LOCAL);
mScope = scope; mScope = scope;
mScanner->NextToken(); mScanner->NextToken();
@ -2725,6 +2801,7 @@ Expression* Parser::ParseAssemblerBaseOperand(Declaration* pcasm, int pcoffset)
exp = new Expression(mScanner->mLocation, EX_CONSTANT); exp = new Expression(mScanner->mLocation, EX_CONSTANT);
dec = new Declaration(mScanner->mLocation, DT_LABEL); dec = new Declaration(mScanner->mLocation, DT_LABEL);
dec->mIdent = mScanner->mTokenIdent; dec->mIdent = mScanner->mTokenIdent;
dec->mQualIdent = mScanner->mTokenIdent;
exp->mDecType = TheUnsignedIntTypeDeclaration; exp->mDecType = TheUnsignedIntTypeDeclaration;
mScope->Insert(dec->mIdent, dec); mScope->Insert(dec->mIdent, dec);
} }
@ -2772,6 +2849,7 @@ Expression* Parser::ParseAssemblerBaseOperand(Declaration* pcasm, int pcoffset)
{ {
Declaration* ndec = new Declaration(mScanner->mLocation, DT_LABEL); Declaration* ndec = new Declaration(mScanner->mLocation, DT_LABEL);
ndec->mIdent = exp->mDecValue->mIdent; ndec->mIdent = exp->mDecValue->mIdent;
ndec->mQualIdent = exp->mDecValue->mQualIdent;
ndec->mBase = exp->mDecValue; ndec->mBase = exp->mDecValue;
ndec->mInteger = 0; ndec->mInteger = 0;
exp->mDecValue = ndec; exp->mDecValue = ndec;
@ -3017,6 +3095,7 @@ void Parser::AddAssemblerRegister(const Ident* ident, int value)
{ {
Declaration* decaccu = new Declaration(mScanner->mLocation, DT_CONST_INTEGER); Declaration* decaccu = new Declaration(mScanner->mLocation, DT_CONST_INTEGER);
decaccu->mIdent = ident; decaccu->mIdent = ident;
decaccu->mQualIdent = ident;
decaccu->mBase = TheUnsignedIntTypeDeclaration; decaccu->mBase = TheUnsignedIntTypeDeclaration;
decaccu->mSize = 2; decaccu->mSize = 2;
decaccu->mInteger = value; decaccu->mInteger = value;
@ -3025,7 +3104,7 @@ void Parser::AddAssemblerRegister(const Ident* ident, int value)
Expression* Parser::ParseAssembler(void) Expression* Parser::ParseAssembler(void)
{ {
DeclarationScope* scope = new DeclarationScope(mScope); DeclarationScope* scope = new DeclarationScope(mScope, SLEVEL_LOCAL);
mScope = scope; mScope = scope;
mScanner->SetAssemblerMode(true); mScanner->SetAssemblerMode(true);
@ -3044,6 +3123,7 @@ Expression* Parser::ParseAssembler(void)
Declaration* decaccu = new Declaration(mScanner->mLocation, DT_CONST_INTEGER); Declaration* decaccu = new Declaration(mScanner->mLocation, DT_CONST_INTEGER);
decaccu->mIdent = Ident::Unique("accu"); decaccu->mIdent = Ident::Unique("accu");
decaccu->mQualIdent = decaccu->mIdent;
decaccu->mBase = TheUnsignedIntTypeDeclaration; decaccu->mBase = TheUnsignedIntTypeDeclaration;
decaccu->mSize = 2; decaccu->mSize = 2;
decaccu->mInteger = BC_REG_ACCU; decaccu->mInteger = BC_REG_ACCU;
@ -3095,6 +3175,7 @@ Expression* Parser::ParseAssembler(void)
dec = new Declaration(mScanner->mLocation, DT_LABEL); dec = new Declaration(mScanner->mLocation, DT_LABEL);
dec->mIdent = label; dec->mIdent = label;
dec->mQualIdent = dec->mIdent;
dec->mValue = ilast; dec->mValue = ilast;
dec->mInteger = offset; dec->mInteger = offset;
dec->mBase = vdasm; dec->mBase = vdasm;
@ -4105,6 +4186,84 @@ void Parser::ParsePragma(void)
mErrors->Error(mScanner->mLocation, EERR_SYNTAX, "Invalid pragma directive"); 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) void Parser::Parse(void)
{ {
mLocalIndex = 0; mLocalIndex = 0;
@ -4144,7 +4303,12 @@ void Parser::Parse(void)
} }
else if (mScanner->mToken == TK_SEMICOLON) else if (mScanner->mToken == TK_SEMICOLON)
mScanner->NextToken(); mScanner->NextToken();
else if (mScanner->mToken == TK_NAMESPACE)
{
mScanner->NextToken();
ParseNamespace();
}
else else
ParseDeclaration(true, false); ParseDeclaration(nullptr, true, false);
} }
} }

View File

@ -13,6 +13,7 @@ public:
DeclarationScope * mGlobals, * mScope; DeclarationScope * mGlobals, * mScope;
int mLocalIndex; int mLocalIndex;
CompilationUnits * mCompilationUnits; CompilationUnits * mCompilationUnits;
Declaration * mNamespace;
LinkerSection * mCodeSection, * mDataSection, * mBSSection; LinkerSection * mCodeSection, * mDataSection, * mBSSection;
@ -33,15 +34,17 @@ protected:
uint8* ParseStringLiteral(int msize); uint8* ParseStringLiteral(int msize);
void ParseNamespace(void);
void ParsePragma(void); void ParsePragma(void);
Declaration* ParseBaseTypeDeclaration(uint64 flags); 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* ParseStructDeclaration(uint64 flags, DecType dt);
Declaration* CopyConstantInitializer(int offset, Declaration* dtype, Expression* exp); Declaration* CopyConstantInitializer(int offset, Declaration* dtype, Expression* exp);
Expression* ParseInitExpression(Declaration* dtype); Expression* ParseInitExpression(Declaration* dtype);
Expression* ParseDeclarationExpression(void); Expression* ParseDeclarationExpression(Declaration* pdec);
Declaration* ParsePostfixDeclaration(void); Declaration* ParsePostfixDeclaration(void);
Declaration* ReverseDeclaration(Declaration* odec, Declaration* bdec); Declaration* ReverseDeclaration(Declaration* odec, Declaration* bdec);
@ -56,6 +59,8 @@ protected:
void AddAssemblerRegister(const Ident* ident, int value); void AddAssemblerRegister(const Ident* ident, int value);
Declaration* ParseQualIdent(void);
Expression* ParseStatement(void); Expression* ParseStatement(void);
Expression* ParseSwitchStatement(void); Expression* ParseSwitchStatement(void);

View File

@ -148,7 +148,11 @@ const char* TokenNames[] =
"'#repeat'", "'#repeat'",
"'#until'", "'#until'",
"'#embed'", "'#embed'",
"'##'" "'##'",
"'namespace'",
"'using'",
"'::'"
}; };
@ -311,7 +315,6 @@ Scanner::Scanner(Errors* errors, Preprocessor* preprocessor)
mToken = TK_NONE; mToken = TK_NONE;
NextChar(); NextChar();
NextToken();
assert(sizeof(TokenNames) == NUM_TOKENS * sizeof(char*)); assert(sizeof(TokenNames) == NUM_TOKENS * sizeof(char*));
} }
@ -1088,6 +1091,11 @@ void Scanner::NextRawToken(void)
case ':': case ':':
mToken = TK_COLON; mToken = TK_COLON;
NextChar(); NextChar();
if (mTokenChar == ':' && (mCompilerOptions & COPT_CPLUSPLUS))
{
mToken = TK_COLCOLON;
NextChar();
}
break; break;
case '?': case '?':
mToken = TK_QUESTIONMARK; mToken = TK_QUESTIONMARK;
@ -1379,6 +1387,10 @@ void Scanner::NextRawToken(void)
mToken = TK_STRIPED; mToken = TK_STRIPED;
else if (!strcmp(tkident, "__dynstack")) else if (!strcmp(tkident, "__dynstack"))
mToken = TK_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 else
{ {
mToken = TK_IDENT; mToken = TK_IDENT;

View File

@ -149,6 +149,10 @@ enum Token
TK_PREP_CONCAT, TK_PREP_CONCAT,
TK_NAMESPACE,
TK_USING,
TK_COLCOLON,
NUM_TOKENS NUM_TOKENS
}; };
@ -231,6 +235,8 @@ public:
bool mAssemblerMode; bool mAssemblerMode;
bool mPreprocessorMode; bool mPreprocessorMode;
uint64 mCompilerOptions;
void AddMacro(const Ident* ident, const char* value); void AddMacro(const Ident* ident, const char* value);
protected: protected:
void NextRawToken(void); void NextRawToken(void);

View File

@ -237,6 +237,11 @@ int main2(int argc, const char** argv)
{ {
compiler->mCompilerOptions |= COPT_EXTENDED_ZERO_PAGE; 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 else
compiler->mErrors->Error(loc, EERR_COMMAND_LINE, "Invalid command line argument", arg); 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]) if (!targetPath[0])
strcpy_s(targetPath, argv[i]); 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); compiler->mCompilationUnits->AddUnit(loc, argv[i], nullptr);
} }
} }