diff --git a/include/opp/algorithm.h b/include/opp/algorithm.h index 56cc828..d3d692e 100644 --- a/include/opp/algorithm.h +++ b/include/opp/algorithm.h @@ -35,6 +35,17 @@ void sort(T s, T e) } } +template +OI copy(II first, II last, OI result) +{ + while (first != last) + { + *result = *first; + ++result; ++first; + } + return result; +} + } #endif diff --git a/include/opp/array.h b/include/opp/array.h index 33d413b..207e2e2 100644 --- a/include/opp/array.h +++ b/include/opp/array.h @@ -9,6 +9,8 @@ class array protected: T _data[n]; public: + typedef T element_type; + int size(void) const { return n; diff --git a/include/opp/iterator.h b/include/opp/iterator.h new file mode 100644 index 0000000..6d50174 --- /dev/null +++ b/include/opp/iterator.h @@ -0,0 +1,137 @@ +#ifndef OPP_ITERATOR_H +#define OPP_ITERATOR_H + +namespace opp +{ + +template +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 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 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 +front_insert_iterator front_inserter (CT & c) +{ + return front_insert_iterator(c); +} + +template +back_insert_iterator back_inserter (CT & c) +{ + return back_insert_iterator(c); +} + +template +insert_iterator inserter (CT & c, const CI & i) +{ + return insert_iterator(c, i); +} + +} diff --git a/include/opp/list.h b/include/opp/list.h new file mode 100644 index 0000000..00b0a20 --- /dev/null +++ b/include/opp/list.h @@ -0,0 +1,286 @@ +#ifndef OPP_LIST +#define OPP_LIST + +namespace opp +{ + +template +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 list_iterator +{ +public: + listnode * node; +public: + list_iterator(void) : node(nullptr) {} + list_iterator(listnode * 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 * 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 * 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 list +{ +private: + listnode node; +public: + typedef T element_type; + typedef list_iterator iterator_type; + + list(void) + {} + + ~list(void) + { + listnode * n = node.succ; + while (n != &node) + { + listnode * m = n->succ; + delete n; + n = m; + } + } + + list_iterator begin(void) + { + return list_iterator(node.succ); + } + + list_iterator end(void) + { + return list_iterator(&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 erase(list_iterator it); + + list_iterator erase(list_iterator first, list_iterator 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 insert(list_iterator it, const T & t); + + list_iterator insert(list_iterator it, T && t); +}; + +template +void list::pop_front(void) +{ + listnode * n = node.succ; + node.succ = n->succ; + n->succ->pred = &node; + delete n; +} + +template +void list::pop_back(void) +{ + listnode * n = node.pred; + node.pred = n->pred; + n->pred->succ = &node; + delete n; +} + +template +void list::push_front(const T & t) +{ + listnode * n = new listnode(t); + n->pred = &node; + n->succ = node.succ; + node.succ->pred = n; + node.succ = n; +} + +template +void list::push_front(T && t) +{ + listnode * n = new listnode(t); + n->pred = &node; + n->succ = node.succ; + node.succ->pred = n; + node.succ = n; +} + +template +void list::push_back(const T & t) +{ + listnode * n = new listnode(t); + n->succ = &node; + n->pred = node.pred; + node.pred->succ = n; + node.pred = n; +} + +template +void list::push_back(T && t) +{ + listnode * n = new listnode(t); + n->succ = &node; + n->pred = node.pred; + node.pred->succ = n; + node.pred = n; +} + + +template +list_iterator list::erase(list_iterator it) +{ + listnode * n = it.node; + listnode * s = n->succ; + + n->succ->pred = n->pred; + n->pred->succ = n->succ; + delete n; + + return list_iterator(s); +} + +template +list_iterator list::erase(list_iterator first, list_iterator last) +{ + listnode * n = first.node; + listnode * s = last.node; + + n->pred->succ = s; + s->pred = n->pred; + + while (n != s) + { + listnode * m = n->succ; + delete n; + n = m; + } + + return list_iterator(s); +} + +template +list_iterator list::insert(list_iterator it, const T & t) +{ + listnode * n = new listnode(t); + n->succ = it.node; + n->pred = it.node->pred; + it.node->pred->succ = n; + it.node->pred = n; + return list_iterator(n); +} + +template +list_iterator list::insert(list_iterator it, T && t) +{ + listnode * n = new listnode(t); + n->succ = it.node; + n->pred = it.node->pred; + it.node->pred->succ = n; + it.node->pred = n; + return list_iterator(n); +} + +} + +#endif diff --git a/include/opp/string.cpp b/include/opp/string.cpp index 38256c2..e9de1c7 100644 --- a/include/opp/string.cpp +++ b/include/opp/string.cpp @@ -1,6 +1,7 @@ #include "string.h" #include #include +#include namespace opp { diff --git a/include/opp/vector.h b/include/opp/vector.h index dde075e..07bd2d2 100644 --- a/include/opp/vector.h +++ b/include/opp/vector.h @@ -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) { diff --git a/oscar64/Declaration.cpp b/oscar64/Declaration.cpp index 7c5f71c..6cdabfe 100644 --- a/oscar64/Declaration.cpp +++ b/oscar64/Declaration.cpp @@ -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) diff --git a/oscar64/Declaration.h b/oscar64/Declaration.h index 29a9fdb..12e4d72 100644 --- a/oscar64/Declaration.h +++ b/oscar64/Declaration.h @@ -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, diff --git a/oscar64/Ident.cpp b/oscar64/Ident.cpp index 29e89f6..9bd9e5c 100644 --- a/oscar64/Ident.cpp +++ b/oscar64/Ident.cpp @@ -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); diff --git a/oscar64/InterCodeGenerator.cpp b/oscar64/InterCodeGenerator.cpp index 2b674f2..ce7a70f 100644 --- a/oscar64/InterCodeGenerator.cpp +++ b/oscar64/InterCodeGenerator.cpp @@ -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>::+insert_iterator")) exp->Dump(0); #endif #if 0 diff --git a/oscar64/NativeCodeGenerator.cpp b/oscar64/NativeCodeGenerator.cpp index 9fdf5f6..d0964bf 100644 --- a/oscar64/NativeCodeGenerator.cpp +++ b/oscar64/NativeCodeGenerator.cpp @@ -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; diff --git a/oscar64/Parser.cpp b/oscar64/Parser.cpp index 5deb802..80982a5 100644 --- a/oscar64/Parser.cpp +++ b/oscar64/Parser.cpp @@ -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; } }