Add list and iterators to opp
This commit is contained in:
parent
82dff88ba8
commit
b7daafcac8
|
@ -35,6 +35,17 @@ void sort(T s, T e)
|
|||
}
|
||||
}
|
||||
|
||||
template<class II, class OI>
|
||||
OI copy(II first, II last, OI result)
|
||||
{
|
||||
while (first != last)
|
||||
{
|
||||
*result = *first;
|
||||
++result; ++first;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -9,6 +9,8 @@ class array
|
|||
protected:
|
||||
T _data[n];
|
||||
public:
|
||||
typedef T element_type;
|
||||
|
||||
int size(void) const
|
||||
{
|
||||
return n;
|
||||
|
|
|
@ -0,0 +1,137 @@
|
|||
#ifndef OPP_ITERATOR_H
|
||||
#define OPP_ITERATOR_H
|
||||
|
||||
namespace opp
|
||||
{
|
||||
|
||||
template <class CT>
|
||||
class back_insert_iterator
|
||||
{
|
||||
protected:
|
||||
CT * co;
|
||||
|
||||
public:
|
||||
back_insert_iterator (CT & c) : co(&c) {}
|
||||
|
||||
back_insert_iterator & operator= (const CT::element_type & t)
|
||||
{
|
||||
co->push_back(t);
|
||||
return *this;
|
||||
}
|
||||
|
||||
back_insert_iterator & operator= (CT::element_type && t)
|
||||
{
|
||||
co->push_back(t);
|
||||
return *this;
|
||||
}
|
||||
|
||||
back_insert_iterator & operator* (void)
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
|
||||
back_insert_iterator & operator++ (void)
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
|
||||
back_insert_iterator operator++ (int)
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
template <class CT>
|
||||
class front_insert_iterator
|
||||
{
|
||||
protected:
|
||||
CT * co;
|
||||
|
||||
public:
|
||||
front_insert_iterator (CT & c) : co(&c) {}
|
||||
|
||||
front_insert_iterator & operator= (const CT::element_type & t)
|
||||
{
|
||||
co->push_front(t);
|
||||
return *this;
|
||||
}
|
||||
|
||||
front_insert_iterator & operator= (CT::element_type && t)
|
||||
{
|
||||
co->push_front(t);
|
||||
return *this;
|
||||
}
|
||||
|
||||
front_insert_iterator & operator* (void)
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
|
||||
front_insert_iterator & operator++ (void)
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
|
||||
front_insert_iterator operator++ (int)
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
template <class CT>
|
||||
class insert_iterator
|
||||
{
|
||||
protected:
|
||||
CT * co;
|
||||
CT::iterator_type ci;
|
||||
|
||||
public:
|
||||
insert_iterator (CT & c, const CT::iterator_type & i) : co(&c), ci(i) {}
|
||||
|
||||
insert_iterator & operator= (const CT::element_type & t)
|
||||
{
|
||||
ci = co->insert(ci, t); ++ci;
|
||||
return *this;
|
||||
}
|
||||
|
||||
insert_iterator & operator= (CT::element_type && t)
|
||||
{
|
||||
ci = co->insert(ci, t); ++ci;
|
||||
return *this;
|
||||
}
|
||||
|
||||
insert_iterator & operator* (void)
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
|
||||
insert_iterator & operator++ (void)
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
|
||||
insert_iterator operator++ (int)
|
||||
{
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
template <class CT>
|
||||
front_insert_iterator<CT> front_inserter (CT & c)
|
||||
{
|
||||
return front_insert_iterator<CT>(c);
|
||||
}
|
||||
|
||||
template <class CT>
|
||||
back_insert_iterator<CT> back_inserter (CT & c)
|
||||
{
|
||||
return back_insert_iterator<CT>(c);
|
||||
}
|
||||
|
||||
template <class CT, class CI>
|
||||
insert_iterator<CT> inserter (CT & c, const CI & i)
|
||||
{
|
||||
return insert_iterator<CT>(c, i);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,286 @@
|
|||
#ifndef OPP_LIST
|
||||
#define OPP_LIST
|
||||
|
||||
namespace opp
|
||||
{
|
||||
|
||||
template <class T>
|
||||
class listnode
|
||||
{
|
||||
public:
|
||||
listnode * succ, * pred;
|
||||
T data;
|
||||
|
||||
listnode()
|
||||
{
|
||||
succ = this;
|
||||
pred = this;
|
||||
}
|
||||
|
||||
listnode(const T & t) : data(t) {}
|
||||
listnode(T && t) : data(t) {}
|
||||
};
|
||||
|
||||
template <class T>
|
||||
class list_iterator
|
||||
{
|
||||
public:
|
||||
listnode<T> * node;
|
||||
public:
|
||||
list_iterator(void) : node(nullptr) {}
|
||||
list_iterator(listnode<T> * n) : node(n) {}
|
||||
list_iterator(const list_iterator & li) : node(li.node) {}
|
||||
list_iterator & operator=(const list_iterator & li)
|
||||
{
|
||||
node = li.node;
|
||||
return *this;
|
||||
}
|
||||
|
||||
T & operator*()
|
||||
{
|
||||
return node->data;
|
||||
}
|
||||
|
||||
list_iterator & operator++(void)
|
||||
{
|
||||
node = node->succ;
|
||||
return *this;
|
||||
}
|
||||
|
||||
list_iterator operator++(int)
|
||||
{
|
||||
listnode<T> * n = node;
|
||||
node = node->succ;
|
||||
return list_iterator(n);
|
||||
}
|
||||
|
||||
list_iterator & operator+=(int n)
|
||||
{
|
||||
while (n--)
|
||||
node = node->succ;
|
||||
return *this;
|
||||
}
|
||||
|
||||
list_iterator & operator--(void)
|
||||
{
|
||||
node = node->pred;
|
||||
return *this;
|
||||
}
|
||||
|
||||
list_iterator operator++(int)
|
||||
{
|
||||
listnode<T> * n = node;
|
||||
node = node->pred;
|
||||
return list_iterator(n);
|
||||
}
|
||||
|
||||
list_iterator & operator-=(int n)
|
||||
{
|
||||
while (n--)
|
||||
node = node->pred;
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool operator==(const list_iterator & li)
|
||||
{
|
||||
return node == li.node;
|
||||
}
|
||||
|
||||
bool operator!=(const list_iterator & li)
|
||||
{
|
||||
return node != li.node;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
template <class T>
|
||||
class list
|
||||
{
|
||||
private:
|
||||
listnode<T> node;
|
||||
public:
|
||||
typedef T element_type;
|
||||
typedef list_iterator<T> iterator_type;
|
||||
|
||||
list(void)
|
||||
{}
|
||||
|
||||
~list(void)
|
||||
{
|
||||
listnode<T> * n = node.succ;
|
||||
while (n != &node)
|
||||
{
|
||||
listnode<T> * m = n->succ;
|
||||
delete n;
|
||||
n = m;
|
||||
}
|
||||
}
|
||||
|
||||
list_iterator<T> begin(void)
|
||||
{
|
||||
return list_iterator<T>(node.succ);
|
||||
}
|
||||
|
||||
list_iterator<T> end(void)
|
||||
{
|
||||
return list_iterator<T>(&node);
|
||||
}
|
||||
|
||||
T & front(void)
|
||||
{
|
||||
return node.succ->data;
|
||||
}
|
||||
|
||||
const T & front(void) const
|
||||
{
|
||||
return node.succ->data;
|
||||
}
|
||||
|
||||
T & back(void)
|
||||
{
|
||||
return node.pred->data;
|
||||
}
|
||||
|
||||
const T & back(void) const
|
||||
{
|
||||
return node.pred->data;
|
||||
}
|
||||
|
||||
list_iterator<T> erase(list_iterator<T> it);
|
||||
|
||||
list_iterator<T> erase(list_iterator<T> first, list_iterator<T> last);
|
||||
|
||||
void pop_front(void);
|
||||
|
||||
void pop_back(void);
|
||||
|
||||
void push_front(const T & t);
|
||||
|
||||
void push_front(T && t);
|
||||
|
||||
void push_back(const T & t);
|
||||
|
||||
void push_back(T && t);
|
||||
|
||||
list_iterator<T> insert(list_iterator<T> it, const T & t);
|
||||
|
||||
list_iterator<T> insert(list_iterator<T> it, T && t);
|
||||
};
|
||||
|
||||
template <class T>
|
||||
void list<T>::pop_front(void)
|
||||
{
|
||||
listnode<T> * n = node.succ;
|
||||
node.succ = n->succ;
|
||||
n->succ->pred = &node;
|
||||
delete n;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void list<T>::pop_back(void)
|
||||
{
|
||||
listnode<T> * n = node.pred;
|
||||
node.pred = n->pred;
|
||||
n->pred->succ = &node;
|
||||
delete n;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void list<T>::push_front(const T & t)
|
||||
{
|
||||
listnode<T> * n = new listnode<T>(t);
|
||||
n->pred = &node;
|
||||
n->succ = node.succ;
|
||||
node.succ->pred = n;
|
||||
node.succ = n;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void list<T>::push_front(T && t)
|
||||
{
|
||||
listnode<T> * n = new listnode<T>(t);
|
||||
n->pred = &node;
|
||||
n->succ = node.succ;
|
||||
node.succ->pred = n;
|
||||
node.succ = n;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void list<T>::push_back(const T & t)
|
||||
{
|
||||
listnode<T> * n = new listnode<T>(t);
|
||||
n->succ = &node;
|
||||
n->pred = node.pred;
|
||||
node.pred->succ = n;
|
||||
node.pred = n;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
void list<T>::push_back(T && t)
|
||||
{
|
||||
listnode<T> * n = new listnode<T>(t);
|
||||
n->succ = &node;
|
||||
n->pred = node.pred;
|
||||
node.pred->succ = n;
|
||||
node.pred = n;
|
||||
}
|
||||
|
||||
|
||||
template <class T>
|
||||
list_iterator<T> list<T>::erase(list_iterator<T> it)
|
||||
{
|
||||
listnode<T> * n = it.node;
|
||||
listnode<T> * s = n->succ;
|
||||
|
||||
n->succ->pred = n->pred;
|
||||
n->pred->succ = n->succ;
|
||||
delete n;
|
||||
|
||||
return list_iterator<T>(s);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
list_iterator<T> list<T>::erase(list_iterator<T> first, list_iterator<T> last)
|
||||
{
|
||||
listnode<T> * n = first.node;
|
||||
listnode<T> * s = last.node;
|
||||
|
||||
n->pred->succ = s;
|
||||
s->pred = n->pred;
|
||||
|
||||
while (n != s)
|
||||
{
|
||||
listnode<T> * m = n->succ;
|
||||
delete n;
|
||||
n = m;
|
||||
}
|
||||
|
||||
return list_iterator<T>(s);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
list_iterator<T> list<T>::insert(list_iterator<T> it, const T & t)
|
||||
{
|
||||
listnode<T> * n = new listnode<T>(t);
|
||||
n->succ = it.node;
|
||||
n->pred = it.node->pred;
|
||||
it.node->pred->succ = n;
|
||||
it.node->pred = n;
|
||||
return list_iterator<T>(n);
|
||||
}
|
||||
|
||||
template <class T>
|
||||
list_iterator<T> list<T>::insert(list_iterator<T> it, T && t)
|
||||
{
|
||||
listnode<T> * n = new listnode<T>(t);
|
||||
n->succ = it.node;
|
||||
n->pred = it.node->pred;
|
||||
it.node->pred->succ = n;
|
||||
it.node->pred = n;
|
||||
return list_iterator<T>(n);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
|
@ -1,6 +1,7 @@
|
|||
#include "string.h"
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
|
||||
namespace opp {
|
||||
|
||||
|
|
|
@ -13,6 +13,8 @@ protected:
|
|||
T * _data;
|
||||
int _size, _capacity;
|
||||
public:
|
||||
typedef T element_type;
|
||||
|
||||
vector(void) : _data(nullptr), _size(0), _capacity(0) {}
|
||||
vector(int n) : _data((T*)malloc(n * sizeof(T))), _size(n), _capacity(n)
|
||||
{
|
||||
|
|
|
@ -203,7 +203,7 @@ void Expression::Dump(int ident) const
|
|||
printf("INDEX");
|
||||
break;
|
||||
case EX_QUALIFY:
|
||||
printf("QUALIFY");
|
||||
printf("QUALIFY<%s>", mDecValue->mIdent->mString);
|
||||
break;
|
||||
case EX_CALL:
|
||||
printf("CALL");
|
||||
|
@ -991,7 +991,9 @@ const Ident* Declaration::MangleIdent(void)
|
|||
Declaration* dec = mParams;
|
||||
while (dec)
|
||||
{
|
||||
mMangleIdent = mMangleIdent->Mangle(dec->mBase->MangleIdent()->mString);
|
||||
const Ident* id = dec->mBase->MangleIdent();
|
||||
if (id)
|
||||
mMangleIdent = mMangleIdent->Mangle(id->mString);
|
||||
dec = dec->mNext;
|
||||
if (dec)
|
||||
mMangleIdent = mMangleIdent->Mangle(",");
|
||||
|
@ -1663,20 +1665,29 @@ bool Declaration::IsSame(const Declaration* dec) const
|
|||
|
||||
bool Declaration::IsTemplateSame(const Declaration* dec, const Declaration * tdec) const
|
||||
{
|
||||
uint64 dflags = dec->mFlags;
|
||||
|
||||
if (dec->mType == DT_TYPE_TEMPLATE)
|
||||
{
|
||||
dec = tdec->mScope->Lookup(dec->mIdent);
|
||||
dflags |= dec->mFlags;
|
||||
}
|
||||
|
||||
if (this == dec)
|
||||
return true;
|
||||
|
||||
if (mType != dec->mType)
|
||||
return false;
|
||||
|
||||
if (dec->mType == DT_TYPE_STRUCT && dec->mTemplate)
|
||||
return true;
|
||||
|
||||
if (mSize != dec->mSize)
|
||||
return false;
|
||||
if (mStripe != dec->mStripe)
|
||||
return false;
|
||||
|
||||
if ((mFlags & (DTF_SIGNED | DTF_CONST | DTF_VOLATILE)) != (dec->mFlags & (DTF_SIGNED | DTF_CONST | DTF_VOLATILE)))
|
||||
if ((mFlags & (DTF_SIGNED | DTF_CONST | DTF_VOLATILE)) != (dflags & (DTF_SIGNED | DTF_CONST | DTF_VOLATILE)))
|
||||
return false;
|
||||
|
||||
if (mType == DT_TYPE_INTEGER)
|
||||
|
|
|
@ -24,10 +24,10 @@ enum DecType
|
|||
DT_TYPE_ARRAY,
|
||||
DT_TYPE_STRUCT,
|
||||
DT_TYPE_UNION,
|
||||
DT_TYPE_TEMPLATE,
|
||||
DT_TYPE_FUNCTION,
|
||||
DT_TYPE_ASSEMBLER,
|
||||
DT_TYPE_AUTO,
|
||||
DT_TYPE_TEMPLATE,
|
||||
|
||||
DT_TYPE_CONST,
|
||||
DT_TYPE_VOLATILE,
|
||||
|
|
|
@ -47,7 +47,7 @@ const Ident* Ident::Unique(const char* str)
|
|||
|
||||
const Ident* Ident::PreMangle(const char* str) const
|
||||
{
|
||||
char buffer[100];
|
||||
char buffer[200];
|
||||
strcpy_s(buffer, str);
|
||||
strcat_s(buffer, mString);
|
||||
return Unique(buffer);
|
||||
|
@ -55,7 +55,7 @@ const Ident* Ident::PreMangle(const char* str) const
|
|||
|
||||
const Ident* Ident::Mangle(const char* str) const
|
||||
{
|
||||
char buffer[100];
|
||||
char buffer[200];
|
||||
strcpy_s(buffer, mString);
|
||||
strcat_s(buffer, str);
|
||||
return Unique(buffer);
|
||||
|
|
|
@ -1152,7 +1152,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateInline(Declaration* pro
|
|||
block->Append(ins);
|
||||
|
||||
ExValue rv(rdec->mBase, ins->mDst.mTemp, 1);
|
||||
if (!rdec->mBase->IsReference())
|
||||
if (!rdec->mBase->IsReference() && rdec->mBase->mType != DT_TYPE_STRUCT)
|
||||
rv = Dereference(proc, exp, block, rv);
|
||||
return rv;
|
||||
}
|
||||
|
@ -3274,6 +3274,11 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
|
|||
}
|
||||
else if (pdec && (pdec->mBase->IsReference() && !vr.mType->IsReference()))
|
||||
vr = Dereference(proc, texp, block, vr, 1);
|
||||
else if (vr.mType->IsReference() && !(pdec && pdec->mBase->IsReference()))
|
||||
{
|
||||
vr.mReference++;
|
||||
vr = Dereference(proc, texp, block, vr);
|
||||
}
|
||||
else
|
||||
vr = Dereference(proc, texp, block, vr);
|
||||
|
||||
|
@ -4706,7 +4711,7 @@ InterCodeProcedure* InterCodeGenerator::TranslateProcedure(InterCodeModule * mod
|
|||
InterCodeProcedure* proc = new InterCodeProcedure(mod, dec->mLocation, dec->mQualIdent, mLinker->AddObject(dec->mLocation, dec->mQualIdent, dec->mSection, LOT_BYTE_CODE, dec->mAlignment));
|
||||
|
||||
#if 0
|
||||
if (proc->mIdent && !strcmp(proc->mIdent->mString, "join"))
|
||||
if (proc->mIdent && !strcmp(proc->mIdent->mString, "opp::insert_iterator<struct opp::list<i16>>::+insert_iterator"))
|
||||
exp->Dump(0);
|
||||
#endif
|
||||
#if 0
|
||||
|
|
|
@ -29989,7 +29989,7 @@ bool NativeCodeBasicBlock::OptimizeSimpleLoopInvariant(NativeCodeProcedure* proc
|
|||
}
|
||||
mIns[i + 1].mType = ASMIT_NOP; mIns[i + 1].mMode = ASMIM_IMPLIED;
|
||||
}
|
||||
else if (j > i && !(mIns[i + 0].mLive & LIVE_MEM) && !(mIns[i + 1].mLive & (LIVE_CPU_REG_A | LIVE_CPU_REG_Z)) && !mExitRequiredRegs[mIns[i + 1].mAddress])
|
||||
else if (j > i && !(mIns[i + 0].mLive & LIVE_MEM) && !(mIns[i + 1].mLive & (LIVE_CPU_REG_A | LIVE_CPU_REG_Z)) && !mExitRequiredRegs[mIns[i + 1].mAddress] && !ReferencesZeroPage(mIns[i + 0].mAddress, 0, i))
|
||||
{
|
||||
int j = mIns.Size() - 1;
|
||||
|
||||
|
|
|
@ -263,81 +263,83 @@ Declaration* Parser::ParseStructDeclaration(uint64 flags, DecType dt)
|
|||
else
|
||||
{
|
||||
Declaration* mdec = ParseDeclaration(nullptr, false, false, pthis);
|
||||
|
||||
mdec->mFlags |= flags & (DTF_PRIVATE | DTF_PROTECTED);
|
||||
|
||||
mdec->mQualIdent = dec->mScope->Mangle(mdec->mIdent);
|
||||
|
||||
int offset = dec->mSize;
|
||||
if (dt == DT_TYPE_UNION)
|
||||
offset = 0;
|
||||
|
||||
if (mdec->mBase->mType == DT_TYPE_FUNCTION)
|
||||
if (mdec)
|
||||
{
|
||||
if (mdec->mBase->mFlags & DTF_VIRTUAL)
|
||||
needVTable = true;
|
||||
mdec->mFlags |= flags & (DTF_PRIVATE | DTF_PROTECTED);
|
||||
|
||||
mdec->mType = DT_CONST_FUNCTION;
|
||||
mdec->mSection = mCodeSection;
|
||||
mdec->mFlags |= DTF_GLOBAL;
|
||||
mdec->mBase->mFlags |= DTF_FUNC_THIS;
|
||||
mdec->mQualIdent = dec->mScope->Mangle(mdec->mIdent);
|
||||
|
||||
if (mCompilerOptions & COPT_NATIVE)
|
||||
mdec->mFlags |= DTF_NATIVE;
|
||||
int offset = dec->mSize;
|
||||
if (dt == DT_TYPE_UNION)
|
||||
offset = 0;
|
||||
|
||||
AddMemberFunction(dec, mdec);
|
||||
}
|
||||
else if ((mCompilerOptions & COPT_CPLUSPLUS) && mdec->mType == DT_ANON)
|
||||
{
|
||||
ConsumeToken(TK_SEMICOLON);
|
||||
// anon element
|
||||
}
|
||||
else
|
||||
{
|
||||
while (mdec)
|
||||
if (mdec->mBase->mType == DT_TYPE_FUNCTION)
|
||||
{
|
||||
if (!(mdec->mBase->mFlags & DTF_DEFINED))
|
||||
mErrors->Error(mdec->mLocation, EERR_UNDEFINED_OBJECT, "Undefined type used in struct member declaration");
|
||||
if (mdec->mBase->mFlags & DTF_VIRTUAL)
|
||||
needVTable = true;
|
||||
|
||||
if (mdec->mType != DT_VARIABLE)
|
||||
{
|
||||
mErrors->Error(mdec->mLocation, EERR_UNDEFINED_OBJECT, "Named structure element expected");
|
||||
break;
|
||||
}
|
||||
mdec->mType = DT_CONST_FUNCTION;
|
||||
mdec->mSection = mCodeSection;
|
||||
mdec->mFlags |= DTF_GLOBAL;
|
||||
mdec->mBase->mFlags |= DTF_FUNC_THIS;
|
||||
|
||||
mdec->mType = DT_ELEMENT;
|
||||
mdec->mOffset = offset;
|
||||
if (mCompilerOptions & COPT_NATIVE)
|
||||
mdec->mFlags |= DTF_NATIVE;
|
||||
|
||||
offset += mdec->mBase->mSize;
|
||||
if (offset > dec->mSize)
|
||||
dec->mSize = offset;
|
||||
|
||||
if (dec->mScope->Insert(mdec->mIdent, mdec))
|
||||
mErrors->Error(mdec->mLocation, EERR_DUPLICATE_DEFINITION, "Duplicate struct member declaration", mdec->mIdent);
|
||||
|
||||
if (dec->mConst)
|
||||
{
|
||||
Declaration* cmdec = mdec->Clone();
|
||||
cmdec->mBase = mdec->mBase->ToConstType();
|
||||
|
||||
dec->mConst->mScope->Insert(cmdec->mIdent, cmdec);
|
||||
dec->mConst->mSize = dec->mSize;
|
||||
}
|
||||
|
||||
if (mlast)
|
||||
mlast->mNext = mdec;
|
||||
else
|
||||
dec->mParams = mdec;
|
||||
mlast = mdec;
|
||||
mdec = mdec->mNext;
|
||||
AddMemberFunction(dec, mdec);
|
||||
}
|
||||
else if ((mCompilerOptions & COPT_CPLUSPLUS) && mdec->mType == DT_ANON)
|
||||
{
|
||||
ConsumeToken(TK_SEMICOLON);
|
||||
// anon element
|
||||
}
|
||||
|
||||
if (mScanner->mToken == TK_SEMICOLON)
|
||||
mScanner->NextToken();
|
||||
else
|
||||
{
|
||||
mErrors->Error(mScanner->mLocation, EERR_SYNTAX, "';' expected");
|
||||
break;
|
||||
while (mdec)
|
||||
{
|
||||
if (!(mdec->mBase->mFlags & DTF_DEFINED))
|
||||
mErrors->Error(mdec->mLocation, EERR_UNDEFINED_OBJECT, "Undefined type used in struct member declaration");
|
||||
|
||||
if (mdec->mType != DT_VARIABLE)
|
||||
{
|
||||
mErrors->Error(mdec->mLocation, EERR_UNDEFINED_OBJECT, "Named structure element expected");
|
||||
break;
|
||||
}
|
||||
|
||||
mdec->mType = DT_ELEMENT;
|
||||
mdec->mOffset = offset;
|
||||
|
||||
offset += mdec->mBase->mSize;
|
||||
if (offset > dec->mSize)
|
||||
dec->mSize = offset;
|
||||
|
||||
if (dec->mScope->Insert(mdec->mIdent, mdec))
|
||||
mErrors->Error(mdec->mLocation, EERR_DUPLICATE_DEFINITION, "Duplicate struct member declaration", mdec->mIdent);
|
||||
|
||||
if (dec->mConst)
|
||||
{
|
||||
Declaration* cmdec = mdec->Clone();
|
||||
cmdec->mBase = mdec->mBase->ToConstType();
|
||||
|
||||
dec->mConst->mScope->Insert(cmdec->mIdent, cmdec);
|
||||
dec->mConst->mSize = dec->mSize;
|
||||
}
|
||||
|
||||
if (mlast)
|
||||
mlast->mNext = mdec;
|
||||
else
|
||||
dec->mParams = mdec;
|
||||
mlast = mdec;
|
||||
mdec = mdec->mNext;
|
||||
}
|
||||
|
||||
if (mScanner->mToken == TK_SEMICOLON)
|
||||
mScanner->NextToken();
|
||||
else
|
||||
{
|
||||
mErrors->Error(mScanner->mLocation, EERR_SYNTAX, "';' expected");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -606,52 +608,55 @@ Declaration* Parser::ParseBaseTypeDeclaration(uint64 flags, bool qualified)
|
|||
|
||||
if (dec && dec->mTemplate)
|
||||
dec = ParseTemplateExpansion(dec->mTemplate, nullptr);
|
||||
}
|
||||
else
|
||||
mScanner->NextToken();
|
||||
|
||||
while (qualified && dec && (dec->mType == DT_TYPE_STRUCT || dec->mType == DT_NAMESPACE) && ConsumeTokenIf(TK_COLCOLON))
|
||||
while (qualified && dec && (dec->mType == DT_TYPE_STRUCT || dec->mType == DT_NAMESPACE) && ConsumeTokenIf(TK_COLCOLON))
|
||||
{
|
||||
if (ExpectToken(TK_IDENT))
|
||||
{
|
||||
if (ExpectToken(TK_IDENT))
|
||||
{
|
||||
pident = mScanner->mTokenIdent;
|
||||
dec = dec->mScope->Lookup(mScanner->mTokenIdent);
|
||||
mScanner->NextToken();
|
||||
}
|
||||
pident = mScanner->mTokenIdent;
|
||||
dec = dec->mScope->Lookup(mScanner->mTokenIdent);
|
||||
mScanner->NextToken();
|
||||
}
|
||||
}
|
||||
|
||||
if (dec && dec->mType <= DT_TYPE_FUNCTION)
|
||||
if (dec && dec->mType <= DT_TYPE_FUNCTION)
|
||||
{
|
||||
if ((flags & ~dec->mFlags) == DTF_CONST)
|
||||
dec = dec->ToConstType();
|
||||
else if (dec->IsSimpleType() && (flags & ~dec->mFlags))
|
||||
{
|
||||
if (dec->IsSimpleType() && (flags & ~dec->mFlags))
|
||||
Declaration* ndec = new Declaration(dec->mLocation, dec->mType);
|
||||
ndec->mFlags = dec->mFlags | flags;
|
||||
ndec->mSize = dec->mSize;
|
||||
ndec->mBase = dec->mBase;
|
||||
dec = ndec;
|
||||
}
|
||||
else if (dec->mType == DT_TYPE_STRUCT && (flags & ~dec->mFlags))
|
||||
{
|
||||
if ((flags & ~dec->mFlags) == DTF_CONST)
|
||||
dec = dec->ToConstType();
|
||||
else
|
||||
{
|
||||
Declaration* ndec = new Declaration(dec->mLocation, dec->mType);
|
||||
ndec->mFlags = dec->mFlags | flags;
|
||||
ndec->mSize = dec->mSize;
|
||||
ndec->mBase = dec->mBase;
|
||||
ndec->mScope = dec->mScope;
|
||||
ndec->mParams = dec->mParams;
|
||||
ndec->mIdent = dec->mIdent;
|
||||
ndec->mQualIdent = dec->mQualIdent;
|
||||
dec = ndec;
|
||||
}
|
||||
else if (dec->mType == DT_TYPE_STRUCT && (flags & ~dec->mFlags))
|
||||
{
|
||||
if ((flags & ~dec->mFlags) == DTF_CONST)
|
||||
dec = dec->ToConstType();
|
||||
else
|
||||
{
|
||||
Declaration* ndec = new Declaration(dec->mLocation, dec->mType);
|
||||
ndec->mFlags = dec->mFlags | flags;
|
||||
ndec->mSize = dec->mSize;
|
||||
ndec->mBase = dec->mBase;
|
||||
ndec->mScope = dec->mScope;
|
||||
ndec->mParams = dec->mParams;
|
||||
ndec->mIdent = dec->mIdent;
|
||||
ndec->mQualIdent = dec->mQualIdent;
|
||||
dec = ndec;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (!dec)
|
||||
mErrors->Error(mScanner->mLocation, EERR_OBJECT_NOT_FOUND, "Identifier not defined", pident);
|
||||
else
|
||||
mErrors->Error(mScanner->mLocation, EERR_NOT_A_TYPE, "Identifier is no type", dec->mQualIdent);
|
||||
}
|
||||
else if (!dec)
|
||||
mErrors->Error(mScanner->mLocation, EERR_OBJECT_NOT_FOUND, "Identifier not defined", pident);
|
||||
else
|
||||
mScanner->NextToken();
|
||||
mErrors->Error(mScanner->mLocation, EERR_NOT_A_TYPE, "Identifier is no type", dec->mQualIdent);
|
||||
|
||||
break;
|
||||
|
||||
case TK_ENUM:
|
||||
|
@ -989,7 +994,7 @@ Declaration * Parser::ParseFunctionDeclaration(Declaration* bdec)
|
|||
}
|
||||
else
|
||||
{
|
||||
if (!(adec->mBase->mFlags & DTF_DEFINED) && adec->mBase->mType != DT_TYPE_ARRAY)
|
||||
if (!(adec->mBase->mFlags & DTF_DEFINED) && adec->mBase->mType != DT_TYPE_ARRAY && !adec->mBase->mTemplate)
|
||||
mErrors->Error(adec->mLocation, EERR_UNDEFINED_OBJECT, "Type of argument not defined");
|
||||
|
||||
adec->mType = DT_ARGUMENT;
|
||||
|
@ -2173,6 +2178,7 @@ void Parser::AddDefaultConstructors(Declaration* pthis)
|
|||
else
|
||||
{
|
||||
mexp = new Expression(mScanner->mLocation, EX_INITIALIZATION);
|
||||
mexp->mToken = TK_ASSIGN;
|
||||
mexp->mLeft = lexp;
|
||||
mexp->mRight = rexp;
|
||||
mexp->mDecType = lexp->mDecType;
|
||||
|
@ -5397,6 +5403,12 @@ Expression* Parser::ParsePostfixExpression(bool lhs)
|
|||
{
|
||||
Expression * pexp = nullptr;
|
||||
|
||||
if (exp->mDecType->mTemplate)
|
||||
{
|
||||
mErrors->Error(mScanner->mLocation, EERR_TEMPLATE_PARAMS, "Missing template parameters", exp->mDecType->mQualIdent);
|
||||
exp->mDecType = TheConstVoidTypeDeclaration;
|
||||
}
|
||||
|
||||
mScanner->NextToken();
|
||||
if (mScanner->mToken != TK_CLOSE_PARENTHESIS)
|
||||
{
|
||||
|
@ -6012,6 +6024,10 @@ Expression* Parser::ParsePrefixExpression(bool lhs)
|
|||
return nexp->mLeft;
|
||||
nexp->mDecType = nexp->mLeft->mDecType->mBase;
|
||||
}
|
||||
else if ((mCompilerOptions & COPT_CPLUSPLUS) && nexp->mLeft->mDecType->mType == DT_TYPE_STRUCT)
|
||||
{
|
||||
nexp->mDecType = nexp->mLeft->mDecType;
|
||||
}
|
||||
else
|
||||
{
|
||||
mErrors->Error(nexp->mLocation, EERR_INCOMPATIBLE_OPERATOR, "Pointer or array type expected");
|
||||
|
@ -7370,10 +7386,16 @@ Declaration* Parser::ParseTemplateExpansion(Declaration* tmpld, Declaration* exp
|
|||
{
|
||||
tdec->mParams = expd->mParams;
|
||||
Declaration* dec = tdec->mParams;
|
||||
Declaration* xdec = tmpld->mParams;
|
||||
while (dec)
|
||||
{
|
||||
tdec->mScope->Insert(dec->mIdent, dec->mBase);
|
||||
if (dec->mBase->mType == DT_TYPE_TEMPLATE)
|
||||
{
|
||||
printf("oopsi");
|
||||
}
|
||||
tdec->mScope->Insert(xdec->mIdent, dec->mBase);
|
||||
dec = dec->mNext;
|
||||
xdec = xdec->mNext;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -7433,6 +7455,21 @@ Declaration* Parser::ParseTemplateExpansion(Declaration* tmpld, Declaration* exp
|
|||
}
|
||||
else
|
||||
{
|
||||
Declaration* epdec = tdec->mParams;
|
||||
while (epdec && epdec->mBase->mType != DT_TYPE_TEMPLATE)
|
||||
epdec = epdec->mNext;
|
||||
|
||||
if (epdec)
|
||||
{
|
||||
// Partial template specification
|
||||
Declaration * bdec = new Declaration(mScanner->mLocation, DT_TYPE_STRUCT);
|
||||
tdec->mBase = bdec;
|
||||
bdec->mTemplate = tdec;
|
||||
bdec->mBase = tmpld->mBase;
|
||||
|
||||
return bdec;
|
||||
}
|
||||
|
||||
Parser* p = tmpld->mParser;
|
||||
|
||||
p->mScanner->Replay(tmpld->mTokens);
|
||||
|
@ -7614,6 +7651,9 @@ void Parser::ParseTemplateDeclaration(void)
|
|||
|
||||
if (adec->mBase->mType == DT_TYPE_FUNCTION)
|
||||
{
|
||||
if (ConsumeTokenIf(TK_CONST))
|
||||
adec->mBase->mFlags |= DTF_CONST;
|
||||
|
||||
adec->mType = DT_CONST_FUNCTION;
|
||||
adec->mSection = mCodeSection;
|
||||
|
||||
|
@ -7642,6 +7682,7 @@ void Parser::ParseTemplateDeclaration(void)
|
|||
mErrors->Error(bdec->mLocation, EERR_FUNCTION_TEMPLATE, "Function template expected");
|
||||
adec->mType = DT_TYPE_VOID;
|
||||
tdec->mBase = adec;
|
||||
adec->mIdent = adec->mQualIdent = Ident::Unique("_");
|
||||
adec->mTemplate = tdec;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue