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;
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++)

View File

@ -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);
}
}

View File

@ -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;

View File

@ -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;
}

View File

@ -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;

View File

@ -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,

View File

@ -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;

View File

@ -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);

View File

@ -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);
}
}

View File

@ -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);

View File

@ -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;

View File

@ -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);

View File

@ -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);
}
}