Add list and iterators to opp

This commit is contained in:
drmortalwombat 2023-08-16 16:16:04 +02:00
parent 82dff88ba8
commit b7daafcac8
12 changed files with 602 additions and 106 deletions

View File

@ -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 #endif

View File

@ -9,6 +9,8 @@ class array
protected: protected:
T _data[n]; T _data[n];
public: public:
typedef T element_type;
int size(void) const int size(void) const
{ {
return n; return n;

137
include/opp/iterator.h Normal file
View File

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

286
include/opp/list.h Normal file
View File

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

View File

@ -1,6 +1,7 @@
#include "string.h" #include "string.h"
#include <string.h> #include <string.h>
#include <stdlib.h> #include <stdlib.h>
#include <math.h>
namespace opp { namespace opp {

View File

@ -13,6 +13,8 @@ protected:
T * _data; T * _data;
int _size, _capacity; int _size, _capacity;
public: public:
typedef T element_type;
vector(void) : _data(nullptr), _size(0), _capacity(0) {} vector(void) : _data(nullptr), _size(0), _capacity(0) {}
vector(int n) : _data((T*)malloc(n * sizeof(T))), _size(n), _capacity(n) vector(int n) : _data((T*)malloc(n * sizeof(T))), _size(n), _capacity(n)
{ {

View File

@ -203,7 +203,7 @@ void Expression::Dump(int ident) const
printf("INDEX"); printf("INDEX");
break; break;
case EX_QUALIFY: case EX_QUALIFY:
printf("QUALIFY"); printf("QUALIFY<%s>", mDecValue->mIdent->mString);
break; break;
case EX_CALL: case EX_CALL:
printf("CALL"); printf("CALL");
@ -991,7 +991,9 @@ const Ident* Declaration::MangleIdent(void)
Declaration* dec = mParams; Declaration* dec = mParams;
while (dec) 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; dec = dec->mNext;
if (dec) if (dec)
mMangleIdent = mMangleIdent->Mangle(","); mMangleIdent = mMangleIdent->Mangle(",");
@ -1663,20 +1665,29 @@ bool Declaration::IsSame(const Declaration* dec) const
bool Declaration::IsTemplateSame(const Declaration* dec, const Declaration * tdec) const bool Declaration::IsTemplateSame(const Declaration* dec, const Declaration * tdec) const
{ {
uint64 dflags = dec->mFlags;
if (dec->mType == DT_TYPE_TEMPLATE) if (dec->mType == DT_TYPE_TEMPLATE)
{
dec = tdec->mScope->Lookup(dec->mIdent); dec = tdec->mScope->Lookup(dec->mIdent);
dflags |= dec->mFlags;
}
if (this == dec) if (this == dec)
return true; return true;
if (mType != dec->mType) if (mType != dec->mType)
return false; return false;
if (dec->mType == DT_TYPE_STRUCT && dec->mTemplate)
return true;
if (mSize != dec->mSize) if (mSize != dec->mSize)
return false; return false;
if (mStripe != dec->mStripe) if (mStripe != dec->mStripe)
return false; 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; return false;
if (mType == DT_TYPE_INTEGER) if (mType == DT_TYPE_INTEGER)

View File

@ -24,10 +24,10 @@ enum DecType
DT_TYPE_ARRAY, DT_TYPE_ARRAY,
DT_TYPE_STRUCT, DT_TYPE_STRUCT,
DT_TYPE_UNION, DT_TYPE_UNION,
DT_TYPE_TEMPLATE,
DT_TYPE_FUNCTION, DT_TYPE_FUNCTION,
DT_TYPE_ASSEMBLER, DT_TYPE_ASSEMBLER,
DT_TYPE_AUTO, DT_TYPE_AUTO,
DT_TYPE_TEMPLATE,
DT_TYPE_CONST, DT_TYPE_CONST,
DT_TYPE_VOLATILE, DT_TYPE_VOLATILE,

View File

@ -47,7 +47,7 @@ const Ident* Ident::Unique(const char* str)
const Ident* Ident::PreMangle(const char* str) const const Ident* Ident::PreMangle(const char* str) const
{ {
char buffer[100]; char buffer[200];
strcpy_s(buffer, str); strcpy_s(buffer, str);
strcat_s(buffer, mString); strcat_s(buffer, mString);
return Unique(buffer); return Unique(buffer);
@ -55,7 +55,7 @@ const Ident* Ident::PreMangle(const char* str) const
const Ident* Ident::Mangle(const char* str) const const Ident* Ident::Mangle(const char* str) const
{ {
char buffer[100]; char buffer[200];
strcpy_s(buffer, mString); strcpy_s(buffer, mString);
strcat_s(buffer, str); strcat_s(buffer, str);
return Unique(buffer); return Unique(buffer);

View File

@ -1152,7 +1152,7 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateInline(Declaration* pro
block->Append(ins); block->Append(ins);
ExValue rv(rdec->mBase, ins->mDst.mTemp, 1); 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); rv = Dereference(proc, exp, block, rv);
return rv; return rv;
} }
@ -3274,6 +3274,11 @@ InterCodeGenerator::ExValue InterCodeGenerator::TranslateExpression(Declaration*
} }
else if (pdec && (pdec->mBase->IsReference() && !vr.mType->IsReference())) else if (pdec && (pdec->mBase->IsReference() && !vr.mType->IsReference()))
vr = Dereference(proc, texp, block, vr, 1); 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 else
vr = Dereference(proc, texp, block, vr); 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)); 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 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); exp->Dump(0);
#endif #endif
#if 0 #if 0

View File

@ -29989,7 +29989,7 @@ bool NativeCodeBasicBlock::OptimizeSimpleLoopInvariant(NativeCodeProcedure* proc
} }
mIns[i + 1].mType = ASMIT_NOP; mIns[i + 1].mMode = ASMIM_IMPLIED; 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; int j = mIns.Size() - 1;

View File

@ -263,7 +263,8 @@ Declaration* Parser::ParseStructDeclaration(uint64 flags, DecType dt)
else else
{ {
Declaration* mdec = ParseDeclaration(nullptr, false, false, pthis); Declaration* mdec = ParseDeclaration(nullptr, false, false, pthis);
if (mdec)
{
mdec->mFlags |= flags & (DTF_PRIVATE | DTF_PROTECTED); mdec->mFlags |= flags & (DTF_PRIVATE | DTF_PROTECTED);
mdec->mQualIdent = dec->mScope->Mangle(mdec->mIdent); mdec->mQualIdent = dec->mScope->Mangle(mdec->mIdent);
@ -342,6 +343,7 @@ Declaration* Parser::ParseStructDeclaration(uint64 flags, DecType dt)
} }
} }
} }
}
if (mlast) if (mlast)
mlast->mNext = nullptr; mlast->mNext = nullptr;
@ -606,6 +608,9 @@ Declaration* Parser::ParseBaseTypeDeclaration(uint64 flags, bool qualified)
if (dec && dec->mTemplate) if (dec && dec->mTemplate)
dec = ParseTemplateExpansion(dec->mTemplate, nullptr); 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))
{ {
@ -619,7 +624,9 @@ Declaration* Parser::ParseBaseTypeDeclaration(uint64 flags, bool qualified)
if (dec && dec->mType <= DT_TYPE_FUNCTION) if (dec && dec->mType <= DT_TYPE_FUNCTION)
{ {
if (dec->IsSimpleType() && (flags & ~dec->mFlags)) if ((flags & ~dec->mFlags) == DTF_CONST)
dec = dec->ToConstType();
else if (dec->IsSimpleType() && (flags & ~dec->mFlags))
{ {
Declaration* ndec = new Declaration(dec->mLocation, dec->mType); Declaration* ndec = new Declaration(dec->mLocation, dec->mType);
ndec->mFlags = dec->mFlags | flags; ndec->mFlags = dec->mFlags | flags;
@ -649,9 +656,7 @@ Declaration* Parser::ParseBaseTypeDeclaration(uint64 flags, bool qualified)
mErrors->Error(mScanner->mLocation, EERR_OBJECT_NOT_FOUND, "Identifier not defined", pident); mErrors->Error(mScanner->mLocation, EERR_OBJECT_NOT_FOUND, "Identifier not defined", pident);
else else
mErrors->Error(mScanner->mLocation, EERR_NOT_A_TYPE, "Identifier is no type", dec->mQualIdent); mErrors->Error(mScanner->mLocation, EERR_NOT_A_TYPE, "Identifier is no type", dec->mQualIdent);
}
else
mScanner->NextToken();
break; break;
case TK_ENUM: case TK_ENUM:
@ -989,7 +994,7 @@ Declaration * Parser::ParseFunctionDeclaration(Declaration* bdec)
} }
else 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"); mErrors->Error(adec->mLocation, EERR_UNDEFINED_OBJECT, "Type of argument not defined");
adec->mType = DT_ARGUMENT; adec->mType = DT_ARGUMENT;
@ -2173,6 +2178,7 @@ void Parser::AddDefaultConstructors(Declaration* pthis)
else else
{ {
mexp = new Expression(mScanner->mLocation, EX_INITIALIZATION); mexp = new Expression(mScanner->mLocation, EX_INITIALIZATION);
mexp->mToken = TK_ASSIGN;
mexp->mLeft = lexp; mexp->mLeft = lexp;
mexp->mRight = rexp; mexp->mRight = rexp;
mexp->mDecType = lexp->mDecType; mexp->mDecType = lexp->mDecType;
@ -5397,6 +5403,12 @@ Expression* Parser::ParsePostfixExpression(bool lhs)
{ {
Expression * pexp = nullptr; 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(); mScanner->NextToken();
if (mScanner->mToken != TK_CLOSE_PARENTHESIS) if (mScanner->mToken != TK_CLOSE_PARENTHESIS)
{ {
@ -6012,6 +6024,10 @@ Expression* Parser::ParsePrefixExpression(bool lhs)
return nexp->mLeft; return nexp->mLeft;
nexp->mDecType = nexp->mLeft->mDecType->mBase; nexp->mDecType = nexp->mLeft->mDecType->mBase;
} }
else if ((mCompilerOptions & COPT_CPLUSPLUS) && nexp->mLeft->mDecType->mType == DT_TYPE_STRUCT)
{
nexp->mDecType = nexp->mLeft->mDecType;
}
else else
{ {
mErrors->Error(nexp->mLocation, EERR_INCOMPATIBLE_OPERATOR, "Pointer or array type expected"); 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; tdec->mParams = expd->mParams;
Declaration* dec = tdec->mParams; Declaration* dec = tdec->mParams;
Declaration* xdec = tmpld->mParams;
while (dec) 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; dec = dec->mNext;
xdec = xdec->mNext;
} }
} }
else else
@ -7433,6 +7455,21 @@ Declaration* Parser::ParseTemplateExpansion(Declaration* tmpld, Declaration* exp
} }
else 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; Parser* p = tmpld->mParser;
p->mScanner->Replay(tmpld->mTokens); p->mScanner->Replay(tmpld->mTokens);
@ -7614,6 +7651,9 @@ void Parser::ParseTemplateDeclaration(void)
if (adec->mBase->mType == DT_TYPE_FUNCTION) if (adec->mBase->mType == DT_TYPE_FUNCTION)
{ {
if (ConsumeTokenIf(TK_CONST))
adec->mBase->mFlags |= DTF_CONST;
adec->mType = DT_CONST_FUNCTION; adec->mType = DT_CONST_FUNCTION;
adec->mSection = mCodeSection; adec->mSection = mCodeSection;
@ -7642,6 +7682,7 @@ void Parser::ParseTemplateDeclaration(void)
mErrors->Error(bdec->mLocation, EERR_FUNCTION_TEMPLATE, "Function template expected"); mErrors->Error(bdec->mLocation, EERR_FUNCTION_TEMPLATE, "Function template expected");
adec->mType = DT_TYPE_VOID; adec->mType = DT_TYPE_VOID;
tdec->mBase = adec; tdec->mBase = adec;
adec->mIdent = adec->mQualIdent = Ident::Unique("_");
adec->mTemplate = tdec; adec->mTemplate = tdec;
} }
} }