diff options
Diffstat (limited to 'nim')
-rw-r--r-- | nim/ast.pas | 154 | ||||
-rw-r--r-- | nim/ccgexprs.pas | 161 | ||||
-rw-r--r-- | nim/ccgstmts.pas | 6 | ||||
-rw-r--r-- | nim/ccgtypes.pas | 20 | ||||
-rw-r--r-- | nim/ccgutils.pas | 9 | ||||
-rw-r--r-- | nim/cgen.pas | 70 | ||||
-rw-r--r-- | nim/commands.pas | 3 | ||||
-rw-r--r-- | nim/condsyms.pas | 3 | ||||
-rw-r--r-- | nim/docgen.pas | 10 | ||||
-rw-r--r-- | nim/ecmasgen.pas | 43 | ||||
-rw-r--r-- | nim/evals.pas | 53 | ||||
-rw-r--r-- | nim/extccomp.pas | 6 | ||||
-rw-r--r-- | nim/magicsys.pas | 1 | ||||
-rw-r--r-- | nim/msgs.pas | 1102 | ||||
-rw-r--r-- | nim/nimconf.pas | 13 | ||||
-rw-r--r-- | nim/nversion.pas | 4 | ||||
-rw-r--r-- | nim/parsecfg.pas | 9 | ||||
-rw-r--r-- | nim/paslex.pas | 10 | ||||
-rw-r--r-- | nim/pnimsyn.pas | 11 | ||||
-rw-r--r-- | nim/pragmas.pas | 9 | ||||
-rw-r--r-- | nim/procfind.pas | 48 | ||||
-rw-r--r-- | nim/rnimsyn.pas | 7 | ||||
-rw-r--r-- | nim/rst.pas | 2 | ||||
-rw-r--r-- | nim/scanner.pas | 60 | ||||
-rw-r--r-- | nim/sem.pas | 4 | ||||
-rw-r--r-- | nim/semexprs.pas | 126 | ||||
-rw-r--r-- | nim/semfold.pas | 25 | ||||
-rw-r--r-- | nim/semstmts.pas | 36 | ||||
-rw-r--r-- | nim/semtypes.pas | 35 | ||||
-rw-r--r-- | nim/sigmatch.pas | 42 | ||||
-rw-r--r-- | nim/transf.pas | 58 | ||||
-rw-r--r-- | nim/transtmp.pas | 2 | ||||
-rw-r--r-- | nim/trees.pas | 4 | ||||
-rw-r--r-- | nim/types.pas | 125 | ||||
-rw-r--r-- | nim/wordrecg.pas | 60 |
35 files changed, 1328 insertions, 1003 deletions
diff --git a/nim/ast.pas b/nim/ast.pas index aa83af4ed..681bf72d5 100644 --- a/nim/ast.pas +++ b/nim/ast.pas @@ -97,8 +97,8 @@ type nkStmtListExpr, nkBlockExpr, nkStmtListType, nkBlockType, nkVm, nkTypeOfExpr, nkObjectTy, nkTupleTy, nkRecList, nkRecCase, nkRecWhen, nkRefTy, - nkPtrTy, nkVarTy, nkProcTy, nkEnumTy, - nkEnumFieldDef, nkReturnToken); + nkPtrTy, nkVarTy, nkAbstractTy, nkProcTy, + nkEnumTy, nkEnumFieldDef, nkReturnToken); TNodeKinds = set of TNodeKind; const NodeKindToStr: array [TNodeKind] of string = ( @@ -132,8 +132,8 @@ const 'nkStmtListExpr', 'nkBlockExpr', 'nkStmtListType', 'nkBlockType', 'nkVm', 'nkTypeOfExpr', 'nkObjectTy', 'nkTupleTy', 'nkRecList', 'nkRecCase', 'nkRecWhen', 'nkRefTy', - 'nkPtrTy', 'nkVarTy', 'nkProcTy', 'nkEnumTy', - 'nkEnumFieldDef', 'nkReturnToken'); + 'nkPtrTy', 'nkVarTy', 'nkAbstractTy', 'nkProcTy', + 'nkEnumTy', 'nkEnumFieldDef', 'nkReturnToken'); type TSymFlag = ( sfUsed, sfStar, sfMinus, sfInInterface, @@ -142,7 +142,8 @@ type sfResult, sfNoSideEffect, sfMainModule, sfSystemModule, sfNoReturn, sfAddrTaken, sfCompilerProc, sfCppMethod, sfDiscriminant, sfDeprecated, sfInClosure, sfTypeCheck, - sfCompileTime, sfThreadVar, sfMerge, sfDeadCodeElim); + sfCompileTime, sfThreadVar, sfMerge, sfDeadCodeElim, + sfBorrow); TSymFlags = set of TSymFlag; const SymFlagToStr: array [TSymFlag] of string = ( @@ -152,30 +153,31 @@ const 'sfResult', 'sfNoSideEffect', 'sfMainModule', 'sfSystemModule', 'sfNoReturn', 'sfAddrTaken', 'sfCompilerProc', 'sfCppMethod', 'sfDiscriminant', 'sfDeprecated', 'sfInClosure', 'sfTypeCheck', - 'sfCompileTime', 'sfThreadVar', 'sfMerge', 'sfDeadCodeElim'); + 'sfCompileTime', 'sfThreadVar', 'sfMerge', 'sfDeadCodeElim', + 'sfBorrow'); type TTypeKind = ( tyNone, tyBool, tyChar, tyEmpty, tyArrayConstr, tyNil, tyGeneric, tyGenericInst, - tyGenericParam, tyEnum, tyAnyEnum, tyArray, - tyObject, tyTuple, tySet, tyRange, - tyPtr, tyRef, tyVar, tySequence, - tyProc, tyPointer, tyOpenArray, tyString, - tyCString, tyForward, tyInt, tyInt8, - tyInt16, tyInt32, tyInt64, tyFloat, - tyFloat32, tyFloat64, tyFloat128); + tyGenericParam, tyAbstract, tyEnum, tyOrdinal, + tyArray, tyObject, tyTuple, tySet, + tyRange, tyPtr, tyRef, tyVar, + tySequence, tyProc, tyPointer, tyOpenArray, + tyString, tyCString, tyForward, tyInt, + tyInt8, tyInt16, tyInt32, tyInt64, + tyFloat, tyFloat32, tyFloat64, tyFloat128); TTypeKinds = set of TTypeKind; const TypeKindToStr: array [TTypeKind] of string = ( 'tyNone', 'tyBool', 'tyChar', 'tyEmpty', 'tyArrayConstr', 'tyNil', 'tyGeneric', 'tyGenericInst', - 'tyGenericParam', 'tyEnum', 'tyAnyEnum', 'tyArray', - 'tyObject', 'tyTuple', 'tySet', 'tyRange', - 'tyPtr', 'tyRef', 'tyVar', 'tySequence', - 'tyProc', 'tyPointer', 'tyOpenArray', 'tyString', - 'tyCString', 'tyForward', 'tyInt', 'tyInt8', - 'tyInt16', 'tyInt32', 'tyInt64', 'tyFloat', - 'tyFloat32', 'tyFloat64', 'tyFloat128'); + 'tyGenericParam', 'tyAbstract', 'tyEnum', 'tyOrdinal', + 'tyArray', 'tyObject', 'tyTuple', 'tySet', + 'tyRange', 'tyPtr', 'tyRef', 'tyVar', + 'tySequence', 'tyProc', 'tyPointer', 'tyOpenArray', + 'tyString', 'tyCString', 'tyForward', 'tyInt', + 'tyInt8', 'tyInt16', 'tyInt32', 'tyInt64', + 'tyFloat', 'tyFloat32', 'tyFloat64', 'tyFloat128'); type TNodeFlag = ( nfNone, nfBase2, nfBase8, nfBase16, @@ -220,36 +222,36 @@ type //cog.outl("m" + magics[-1]) //]]] mNone, mDefined, mLow, mHigh, mSizeOf, mIs, - mSucc, mPred, mInc, mDec, mOrd, mNew, - mNewFinalize, mNewSeq, mRegisterFinalizer, mLengthOpenArray, mLengthStr, mLengthArray, - mLengthSeq, mIncl, mExcl, mCard, mChr, mGCref, - mGCunref, mAddI, mSubI, mMulI, mDivI, mModI, - mAddI64, mSubI64, mMulI64, mDivI64, mModI64, mShrI, - mShlI, mBitandI, mBitorI, mBitxorI, mMinI, mMaxI, - mShrI64, mShlI64, mBitandI64, mBitorI64, mBitxorI64, mMinI64, - mMaxI64, mAddF64, mSubF64, mMulF64, mDivF64, mMinF64, - mMaxF64, mAddU, mSubU, mMulU, mDivU, mModU, - mAddU64, mSubU64, mMulU64, mDivU64, mModU64, mEqI, - mLeI, mLtI, mEqI64, mLeI64, mLtI64, mEqF64, - mLeF64, mLtF64, mLeU, mLtU, mLeU64, mLtU64, - mEqEnum, mLeEnum, mLtEnum, mEqCh, mLeCh, mLtCh, - mEqB, mLeB, mLtB, mEqRef, mEqProc, mEqUntracedRef, - mLePtr, mLtPtr, mEqCString, mXor, mUnaryMinusI, mUnaryMinusI64, - mAbsI, mAbsI64, mNot, mUnaryPlusI, mBitnotI, mUnaryPlusI64, - mBitnotI64, mUnaryPlusF64, mUnaryMinusF64, mAbsF64, mZe8ToI, mZe8ToI64, - mZe16ToI, mZe16ToI64, mZe32ToI64, mZeIToI64, mToU8, mToU16, - mToU32, mToFloat, mToBiggestFloat, mToInt, mToBiggestInt, mCharToStr, - mBoolToStr, mIntToStr, mInt64ToStr, mFloatToStr, mCStrToStr, mStrToStr, - mEnumToStr, mAnd, mOr, mEqStr, mLeStr, mLtStr, - mEqSet, mLeSet, mLtSet, mMulSet, mPlusSet, mMinusSet, - mSymDiffSet, mConStrStr, mConArrArr, mConArrT, mConTArr, mConTT, - mSlice, mAppendStrCh, mAppendStrStr, mAppendSeqElem, mAppendSeqSeq, mInRange, - mInSet, mAsgn, mRepr, mExit, mSetLengthStr, mSetLengthSeq, + mEcho, mSucc, mPred, mInc, mDec, mOrd, + mNew, mNewFinalize, mNewSeq, mRegisterFinalizer, mLengthOpenArray, mLengthStr, + mLengthArray, mLengthSeq, mIncl, mExcl, mCard, mChr, + mGCref, mGCunref, mAddI, mSubI, mMulI, mDivI, + mModI, mAddI64, mSubI64, mMulI64, mDivI64, mModI64, + mShrI, mShlI, mBitandI, mBitorI, mBitxorI, mMinI, + mMaxI, mShrI64, mShlI64, mBitandI64, mBitorI64, mBitxorI64, + mMinI64, mMaxI64, mAddF64, mSubF64, mMulF64, mDivF64, + mMinF64, mMaxF64, mAddU, mSubU, mMulU, mDivU, + mModU, mAddU64, mSubU64, mMulU64, mDivU64, mModU64, + mEqI, mLeI, mLtI, mEqI64, mLeI64, mLtI64, + mEqF64, mLeF64, mLtF64, mLeU, mLtU, mLeU64, + mLtU64, mEqEnum, mLeEnum, mLtEnum, mEqCh, mLeCh, + mLtCh, mEqB, mLeB, mLtB, mEqRef, mEqProc, + mEqUntracedRef, mLePtr, mLtPtr, mEqCString, mXor, mUnaryMinusI, + mUnaryMinusI64, mAbsI, mAbsI64, mNot, mUnaryPlusI, mBitnotI, + mUnaryPlusI64, mBitnotI64, mUnaryPlusF64, mUnaryMinusF64, mAbsF64, mZe8ToI, + mZe8ToI64, mZe16ToI, mZe16ToI64, mZe32ToI64, mZeIToI64, mToU8, + mToU16, mToU32, mToFloat, mToBiggestFloat, mToInt, mToBiggestInt, + mCharToStr, mBoolToStr, mIntToStr, mInt64ToStr, mFloatToStr, mCStrToStr, + mStrToStr, mEnumToStr, mAnd, mOr, mEqStr, mLeStr, + mLtStr, mEqSet, mLeSet, mLtSet, mMulSet, mPlusSet, + mMinusSet, mSymDiffSet, mConStrStr, mConArrArr, mConArrT, mConTArr, + mConTT, mSlice, mAppendStrCh, mAppendStrStr, mAppendSeqElem, mAppendSeqSeq, + mInRange, mInSet, mRepr, mExit, mSetLengthStr, mSetLengthSeq, mAssert, mSwap, mIsNil, mArrToSeq, mCopyStr, mCopyStrLast, mNewString, mArray, mOpenArray, mRange, mSet, mSeq, - mInt, mInt8, mInt16, mInt32, mInt64, mFloat, - mFloat32, mFloat64, mBool, mChar, mString, mCstring, - mPointer, mAnyEnum, mEmptySet, mIntSetBaseType, mNil, mIsMainModule, + mOrdinal, mInt, mInt8, mInt16, mInt32, mInt64, + mFloat, mFloat32, mFloat64, mBool, mChar, mString, + mCstring, mPointer, mEmptySet, mIntSetBaseType, mNil, mIsMainModule, mCompileDate, mCompileTime, mNimrodVersion, mNimrodMajor, mNimrodMinor, mNimrodPatch, mCpuEndian, mHostOS, mHostCPU, mNaN, mInf, mNegInf, mNLen, mNChild, mNSetChild, mNAdd, mNAddMultiple, mNDel, @@ -479,36 +481,36 @@ const // "MagicToStr" array: //cog.outl("'%s'" % magics[-1]) //]]] 'None', 'Defined', 'Low', 'High', 'SizeOf', 'Is', - 'Succ', 'Pred', 'Inc', 'Dec', 'Ord', 'New', - 'NewFinalize', 'NewSeq', 'RegisterFinalizer', 'LengthOpenArray', 'LengthStr', 'LengthArray', - 'LengthSeq', 'Incl', 'Excl', 'Card', 'Chr', 'GCref', - 'GCunref', 'AddI', 'SubI', 'MulI', 'DivI', 'ModI', - 'AddI64', 'SubI64', 'MulI64', 'DivI64', 'ModI64', 'ShrI', - 'ShlI', 'BitandI', 'BitorI', 'BitxorI', 'MinI', 'MaxI', - 'ShrI64', 'ShlI64', 'BitandI64', 'BitorI64', 'BitxorI64', 'MinI64', - 'MaxI64', 'AddF64', 'SubF64', 'MulF64', 'DivF64', 'MinF64', - 'MaxF64', 'AddU', 'SubU', 'MulU', 'DivU', 'ModU', - 'AddU64', 'SubU64', 'MulU64', 'DivU64', 'ModU64', 'EqI', - 'LeI', 'LtI', 'EqI64', 'LeI64', 'LtI64', 'EqF64', - 'LeF64', 'LtF64', 'LeU', 'LtU', 'LeU64', 'LtU64', - 'EqEnum', 'LeEnum', 'LtEnum', 'EqCh', 'LeCh', 'LtCh', - 'EqB', 'LeB', 'LtB', 'EqRef', 'EqProc', 'EqUntracedRef', - 'LePtr', 'LtPtr', 'EqCString', 'Xor', 'UnaryMinusI', 'UnaryMinusI64', - 'AbsI', 'AbsI64', 'Not', 'UnaryPlusI', 'BitnotI', 'UnaryPlusI64', - 'BitnotI64', 'UnaryPlusF64', 'UnaryMinusF64', 'AbsF64', 'Ze8ToI', 'Ze8ToI64', - 'Ze16ToI', 'Ze16ToI64', 'Ze32ToI64', 'ZeIToI64', 'ToU8', 'ToU16', - 'ToU32', 'ToFloat', 'ToBiggestFloat', 'ToInt', 'ToBiggestInt', 'CharToStr', - 'BoolToStr', 'IntToStr', 'Int64ToStr', 'FloatToStr', 'CStrToStr', 'StrToStr', - 'EnumToStr', 'And', 'Or', 'EqStr', 'LeStr', 'LtStr', - 'EqSet', 'LeSet', 'LtSet', 'MulSet', 'PlusSet', 'MinusSet', - 'SymDiffSet', 'ConStrStr', 'ConArrArr', 'ConArrT', 'ConTArr', 'ConTT', - 'Slice', 'AppendStrCh', 'AppendStrStr', 'AppendSeqElem', 'AppendSeqSeq', 'InRange', - 'InSet', 'Asgn', 'Repr', 'Exit', 'SetLengthStr', 'SetLengthSeq', + 'Echo', 'Succ', 'Pred', 'Inc', 'Dec', 'Ord', + 'New', 'NewFinalize', 'NewSeq', 'RegisterFinalizer', 'LengthOpenArray', 'LengthStr', + 'LengthArray', 'LengthSeq', 'Incl', 'Excl', 'Card', 'Chr', + 'GCref', 'GCunref', 'AddI', 'SubI', 'MulI', 'DivI', + 'ModI', 'AddI64', 'SubI64', 'MulI64', 'DivI64', 'ModI64', + 'ShrI', 'ShlI', 'BitandI', 'BitorI', 'BitxorI', 'MinI', + 'MaxI', 'ShrI64', 'ShlI64', 'BitandI64', 'BitorI64', 'BitxorI64', + 'MinI64', 'MaxI64', 'AddF64', 'SubF64', 'MulF64', 'DivF64', + 'MinF64', 'MaxF64', 'AddU', 'SubU', 'MulU', 'DivU', + 'ModU', 'AddU64', 'SubU64', 'MulU64', 'DivU64', 'ModU64', + 'EqI', 'LeI', 'LtI', 'EqI64', 'LeI64', 'LtI64', + 'EqF64', 'LeF64', 'LtF64', 'LeU', 'LtU', 'LeU64', + 'LtU64', 'EqEnum', 'LeEnum', 'LtEnum', 'EqCh', 'LeCh', + 'LtCh', 'EqB', 'LeB', 'LtB', 'EqRef', 'EqProc', + 'EqUntracedRef', 'LePtr', 'LtPtr', 'EqCString', 'Xor', 'UnaryMinusI', + 'UnaryMinusI64', 'AbsI', 'AbsI64', 'Not', 'UnaryPlusI', 'BitnotI', + 'UnaryPlusI64', 'BitnotI64', 'UnaryPlusF64', 'UnaryMinusF64', 'AbsF64', 'Ze8ToI', + 'Ze8ToI64', 'Ze16ToI', 'Ze16ToI64', 'Ze32ToI64', 'ZeIToI64', 'ToU8', + 'ToU16', 'ToU32', 'ToFloat', 'ToBiggestFloat', 'ToInt', 'ToBiggestInt', + 'CharToStr', 'BoolToStr', 'IntToStr', 'Int64ToStr', 'FloatToStr', 'CStrToStr', + 'StrToStr', 'EnumToStr', 'And', 'Or', 'EqStr', 'LeStr', + 'LtStr', 'EqSet', 'LeSet', 'LtSet', 'MulSet', 'PlusSet', + 'MinusSet', 'SymDiffSet', 'ConStrStr', 'ConArrArr', 'ConArrT', 'ConTArr', + 'ConTT', 'Slice', 'AppendStrCh', 'AppendStrStr', 'AppendSeqElem', 'AppendSeqSeq', + 'InRange', 'InSet', 'Repr', 'Exit', 'SetLengthStr', 'SetLengthSeq', 'Assert', 'Swap', 'IsNil', 'ArrToSeq', 'CopyStr', 'CopyStrLast', 'NewString', 'Array', 'OpenArray', 'Range', 'Set', 'Seq', - 'Int', 'Int8', 'Int16', 'Int32', 'Int64', 'Float', - 'Float32', 'Float64', 'Bool', 'Char', 'String', 'Cstring', - 'Pointer', 'AnyEnum', 'EmptySet', 'IntSetBaseType', 'Nil', 'IsMainModule', + 'Ordinal', 'Int', 'Int8', 'Int16', 'Int32', 'Int64', + 'Float', 'Float32', 'Float64', 'Bool', 'Char', 'String', + 'Cstring', 'Pointer', 'EmptySet', 'IntSetBaseType', 'Nil', 'IsMainModule', 'CompileDate', 'CompileTime', 'NimrodVersion', 'NimrodMajor', 'NimrodMinor', 'NimrodPatch', 'CpuEndian', 'HostOS', 'HostCPU', 'NaN', 'Inf', 'NegInf', 'NLen', 'NChild', 'NSetChild', 'NAdd', 'NAddMultiple', 'NDel', diff --git a/nim/ccgexprs.pas b/nim/ccgexprs.pas index a7a364a52..bf03365cd 100644 --- a/nim/ccgexprs.pas +++ b/nim/ccgexprs.pas @@ -56,7 +56,7 @@ begin if ty = nil then internalError(v.info, 'genLiteral: ty is nil'); case v.kind of nkCharLit..nkInt64Lit: begin - case skipVarGenericRange(ty).kind of + case skipTypes(ty, abstractVarRange).kind of tyChar, tyInt64, tyNil: result := intLiteral(v.intVal); tyInt8: result := ropef('((NI8) $1)', [intLiteral(biggestInt(int8(v.intVal)))]); @@ -76,13 +76,13 @@ begin end; else result := ropef('(($1) $2)', [getTypeDesc(p.module, - skipVarGenericRange(ty)), intLiteral(v.intVal)]) + skipTypes(ty, abstractVarRange)), intLiteral(v.intVal)]) end end; nkNilLit: result := toRope('0'+''); nkStrLit..nkTripleStrLit: begin - if skipVarGenericRange(ty).kind = tyString then begin + if skipTypes(ty, abstractVarRange).kind = tyString then begin id := NodeTableTestOrSet(p.module.dataCache, v, gid); if id = gid then begin // string literal not found in the cache: @@ -228,7 +228,7 @@ function rdCharLoc(const a: TLoc): PRope; // read a location that may need a char-cast: begin result := rdLoc(a); - if skipRange(a.t).kind = tyChar then + if skipTypes(a.t, abstractRange).kind = tyChar then result := ropef('((NU8)($1))', [result]) end; @@ -289,7 +289,7 @@ procedure genAssignment(p: BProc; const dest, src: TLoc; var ty: PType; begin; - ty := skipVarGenericRange(dest.t); + ty := skipTypes(dest.t, abstractVarRange); case ty.kind of tyRef: genRefAssign(p, dest, src, flags); @@ -531,7 +531,7 @@ begin assert(e.sons[2].typ <> nil); InitLocExpr(p, e.sons[1], a); InitLocExpr(p, e.sons[2], b); - t := skipGenericRange(e.typ); + t := skipTypes(e.typ, abstractRange); if getSize(t) >= platform.IntSize then begin if optOverflowCheck in p.options then begin useMagic(p.module, prc[m]); @@ -578,7 +578,7 @@ var begin assert(e.sons[1].typ <> nil); InitLocExpr(p, e.sons[1], a); - t := skipGenericRange(e.typ); + t := skipTypes(e.typ, abstractRange); if optOverflowCheck in p.options then begin useMagic(p.module, 'raiseOverflow'); appf(p.s[cpsStmts], 'if ($1 == $2) raiseOverflow();$n', @@ -705,7 +705,7 @@ var begin assert(e.sons[1].typ <> nil); InitLocExpr(p, e.sons[1], a); - t := skipGenericRange(e.typ); + t := skipTypes(e.typ, abstractRange); putIntoDest(p, d, e.typ, ropef(unArithTab[op], [rdLoc(a), toRope(getSize(t)*8)])); end; @@ -718,7 +718,7 @@ begin expr(p, e.sons[0], d) else begin initLocExpr(p, e.sons[0], a); - case skipGeneric(a.t).kind of + case skipTypes(a.t, abstractInst).kind of tyRef: d.s := OnHeap; tyVar: d.s := OnUnknown; tyPtr: d.s := OnUnknown; // BUGFIX! @@ -872,7 +872,7 @@ var begin initLocExpr(p, e.sons[0], a); initLocExpr(p, e.sons[1], b); - ty := skipPtrsGeneric(skipVarGenericRange(a.t)); + ty := skipTypes(skipTypes(a.t, abstractVarRange), abstractPtrs); first := intLiteral(firstOrd(ty)); // emit range check: if (optBoundsCheck in p.options) then begin @@ -892,7 +892,7 @@ begin end; end; if d.k = locNone then d.s := a.s; - putIntoDest(p, d, elemType(skipVarGeneric(ty)), ropef('$1[($2)-$3]', + putIntoDest(p, d, elemType(skipTypes(ty, abstractVar)), ropef('$1[($2)-$3]', [rdLoc(a), rdCharLoc(b), first])); end; @@ -903,9 +903,9 @@ var begin initLocExpr(p, e.sons[0], a); initLocExpr(p, e.sons[1], b); - ty := skipVarGenericRange(a.t); + ty := skipTypes(a.t, abstractVarRange); if d.k = locNone then d.s := a.s; - putIntoDest(p, d, elemType(skipVarGeneric(ty)), ropef('$1[$2]', + putIntoDest(p, d, elemType(skipTypes(ty, abstractVar)), ropef('$1[$2]', [rdLoc(a), rdCharLoc(b)])); end; @@ -923,7 +923,7 @@ begin // BUGFIX: ``>=`` and not ``>``! end; if d.k = locNone then d.s := a.s; - putIntoDest(p, d, elemType(skipVarGeneric(a.t)), ropef('$1[$2]', + putIntoDest(p, d, elemType(skipTypes(a.t, abstractVar)), ropef('$1[$2]', [rdLoc(a), rdCharLoc(b)])); end; @@ -934,8 +934,9 @@ var begin initLocExpr(p, e.sons[0], a); initLocExpr(p, e.sons[1], b); - ty := skipVarGenericRange(a.t); - if ty.kind in [tyRef, tyPtr] then ty := skipVarGenericRange(ty.sons[0]); + ty := skipTypes(a.t, abstractVarRange); + if ty.kind in [tyRef, tyPtr] then + ty := skipTypes(ty.sons[0], abstractVarRange); // emit range check: if (optBoundsCheck in p.options) then begin useMagic(p.module, 'raiseIndexError'); @@ -949,10 +950,10 @@ begin [rdLoc(b), rdLoc(a)]) end; if d.k = locNone then d.s := OnHeap; - if skipVarGenericRange(a.t).kind in [tyRef, tyPtr] then + if skipTypes(a.t, abstractVar).kind in [tyRef, tyPtr] then a.r := ropef('(*$1)', [a.r]); - putIntoDest(p, d, elemType(skipVarGeneric(a.t)), ropef('$1->data[$2]', - [rdLoc(a), rdCharLoc(b)])); + putIntoDest(p, d, elemType(skipTypes(a.t, abstractVar)), + ropef('$1->data[$2]', [rdLoc(a), rdCharLoc(b)])); end; procedure genAndOr(p: BProc; e: PNode; var d: TLoc; m: TMagic); @@ -1040,6 +1041,20 @@ begin genAssignment(p, d, tmp, {@set}[]); // no need for deep copying end; +procedure genEcho(p: BProc; n: PNode); +var + i: int; + a: TLoc; +begin + useMagic(p.module, 'rawEcho'); + useMagic(p.module, 'rawEchoNL'); + for i := 1 to sonsLen(n)-1 do begin + initLocExpr(p, n.sons[i], a); + appf(p.s[cpsStmts], 'rawEcho($1);$n', [rdLoc(a)]); + end; + app(p.s[cpsStmts], 'rawEchoNL();' + tnl); +end; + procedure genCall(p: BProc; t: PNode; var d: TLoc); var param: PSym; @@ -1120,7 +1135,7 @@ begin for i := 0 to sonsLen(e)-2 do begin // compute the length expression: initLocExpr(p, e.sons[i+1], a); - if skipVarGenericRange(e.sons[i+1].Typ).kind = tyChar then begin + if skipTypes(e.sons[i+1].Typ, abstractVarRange).kind = tyChar then begin Inc(L); useMagic(p.module, 'appendChar'); appf(appends, 'appendChar($1, $2);$n', [tmp.r, rdLoc(a)]) @@ -1169,7 +1184,7 @@ begin for i := 0 to sonsLen(e)-3 do begin // compute the length expression: initLocExpr(p, e.sons[i+2], a); - if skipVarGenericRange(e.sons[i+2].Typ).kind = tyChar then begin + if skipTypes(e.sons[i+2].Typ, abstractVarRange).kind = tyChar then begin Inc(L); useMagic(p.module, 'appendChar'); appf(appends, 'appendChar($1, $2);$n', @@ -1202,8 +1217,8 @@ begin InitLocExpr(p, e.sons[2], b); appf(p.s[cpsStmts], '$1 = ($2) incrSeq(&($1)->Sup, sizeof($3));$n', - [rdLoc(a), getTypeDesc(p.module, skipVarGeneric(e.sons[1].typ)), - getTypeDesc(p.module, skipVarGeneric(e.sons[2].Typ))]); + [rdLoc(a), getTypeDesc(p.module, skipTypes(e.sons[1].typ, abstractVar)), + getTypeDesc(p.module, skipTypes(e.sons[2].Typ, abstractVar))]); initLoc(dest, locExpr, b.t, OnHeap); dest.r := ropef('$1->data[$1->Sup.len-1]', [rdLoc(a)]); genAssignment(p, dest, b, {@set}[needToCopy, afDestIsNil]); @@ -1222,7 +1237,7 @@ begin s := t; while (s.kind = tyObject) and (s.sons[0] <> nil) do begin app(r, '.Sup'); - s := skipGeneric(s.sons[0]); + s := skipTypes(s.sons[0], abstractInst); end; appf(p.s[cpsStmts], '$1.m_type = $2;$n', [r, genTypeInfo(p.module, t)]) end; @@ -1242,15 +1257,15 @@ var reftype, bt: PType; begin useMagic(p.module, 'newObj'); - refType := skipVarGenericRange(e.sons[1].typ); + refType := skipTypes(e.sons[1].typ, abstractVarRange); InitLocExpr(p, e.sons[1], a); initLoc(b, locExpr, a.t, OnHeap); b.r := ropef('($1) newObj($2, sizeof($3))', [getTypeDesc(p.module, reftype), genTypeInfo(p.module, refType), - getTypeDesc(p.module, skipGenericRange(reftype.sons[0]))]); + getTypeDesc(p.module, skipTypes(reftype.sons[0], abstractRange))]); genAssignment(p, a, b, {@set}[]); // set the object type: - bt := skipGenericRange(refType.sons[0]); + bt := skipTypes(refType.sons[0], abstractRange); genObjectInit(p, bt, a, false); end; @@ -1260,7 +1275,7 @@ var seqtype: PType; begin useMagic(p.module, 'newSeq'); - seqType := skipVarGenericRange(e.sons[1].typ); + seqType := skipTypes(e.sons[1].typ, abstractVarRange); InitLocExpr(p, e.sons[1], a); InitLocExpr(p, e.sons[2], b); initLoc(c, locExpr, a.t, OnHeap); @@ -1278,20 +1293,20 @@ var r, nilcheck: PRope; begin initLocExpr(p, n.sons[1], a); - dest := skipPtrsGeneric(n.sons[2].typ); + dest := skipTypes(n.sons[2].typ, abstractPtrs); useMagic(p.module, 'isObj'); r := rdLoc(a); nilCheck := nil; - t := skipGeneric(a.t); + t := skipTypes(a.t, abstractInst); while t.kind in [tyVar, tyPtr, tyRef] do begin if t.kind <> tyVar then nilCheck := r; r := ropef('(*$1)', [r]); - t := skipGeneric(t.sons[0]) + t := skipTypes(t.sons[0], abstractInst) end; if gCmd <> cmdCompileToCpp then while (t.kind = tyObject) and (t.sons[0] <> nil) do begin app(r, '.Sup'); - t := skipGeneric(t.sons[0]); + t := skipTypes(t.sons[0], abstractInst) end; if nilCheck <> nil then r := ropef('(($1) && isObj($2.m_type, $3))', @@ -1310,7 +1325,7 @@ var oldModule: BModule; begin useMagic(p.module, 'newObj'); - refType := skipVarGenericRange(e.sons[1].typ); + refType := skipTypes(e.sons[1].typ, abstractVarRange); InitLocExpr(p, e.sons[1], a); // This is a little hack: @@ -1326,11 +1341,11 @@ begin appf(gmti.s[cfsTypeInit3], '$1->finalizer = (void*)$2;$n', [ ti, rdLoc(f)]); b.r := ropef('($1) newObj($2, sizeof($3))', - [getTypeDesc(p.module, refType), ti, - getTypeDesc(p.module, skipGenericRange(reftype.sons[0]))]); + [getTypeDesc(p.module, refType), ti, + getTypeDesc(p.module, skipTypes(reftype.sons[0], abstractRange))]); genAssignment(p, a, b, {@set}[]); // set the object type: - bt := skipGenericRange(refType.sons[0]); + bt := skipTypes(refType.sons[0], abstractRange); genObjectInit(p, bt, a, false); end; @@ -1340,7 +1355,7 @@ var t: PType; begin InitLocExpr(p, e.sons[1], a); - t := skipVarGenericRange(e.sons[1].typ); + t := skipTypes(e.sons[1].typ, abstractVarRange); case t.kind of tyInt..tyInt64: begin UseMagic(p.module, 'reprInt'); @@ -1358,7 +1373,7 @@ begin UseMagic(p.module, 'reprChar'); putIntoDest(p, d, e.typ, ropef('reprChar($1)', [rdLoc(a)])) end; - tyEnum, tyAnyEnum: begin + tyEnum, tyOrdinal: begin UseMagic(p.module, 'reprEnum'); putIntoDest(p, d, e.typ, ropef('reprEnum($1, $2)', [rdLoc(a), genTypeInfo(p.module, t)])) @@ -1416,7 +1431,7 @@ procedure genArrayLen(p: BProc; e: PNode; var d: TLoc; op: TMagic); var typ: PType; begin - typ := skipPtrsGeneric(e.sons[1].Typ); + typ := skipTypes(e.sons[1].Typ, abstractPtrs); case typ.kind of tyOpenArray: begin while e.sons[1].kind = nkPassAsOpenArray do @@ -1457,7 +1472,7 @@ begin useMagic(p.module, 'setLengthSeq'); InitLocExpr(p, e.sons[1], a); InitLocExpr(p, e.sons[2], b); - t := skipVarGeneric(e.sons[1].typ); + t := skipTypes(e.sons[1].typ, abstractVar); appf(p.s[cpsStmts], '$1 = ($3) setLengthSeq(&($1)->Sup, sizeof($4), $2);$n', [rdLoc(a), rdLoc(b), getTypeDesc(p.module, t), @@ -1477,7 +1492,7 @@ procedure genSwap(p: BProc; e: PNode; var d: TLoc); var a, b, tmp: TLoc; begin - getTemp(p, skipVarGeneric(e.sons[1].typ), tmp); + getTemp(p, skipTypes(e.sons[1].typ, abstractVar), tmp); InitLocExpr(p, e.sons[1], a); // eval a InitLocExpr(p, e.sons[2], b); // eval b genAssignment(p, tmp, a, {@set}[]); @@ -1518,7 +1533,7 @@ end; procedure genInExprAux(p: BProc; e: PNode; var a, b, d: TLoc); begin - case int(getSize(skipVarGeneric(e.sons[1].typ))) of + case int(getSize(skipTypes(e.sons[1].typ, abstractVar))) of 1: binaryExprIn(p, e, a, b, d, '(($1 &(1<<(($2)&7)))!=0)'); 2: binaryExprIn(p, e, a, b, d, '(($1 &(1<<(($2)&15)))!=0)'); 4: binaryExprIn(p, e, a, b, d, '(($1 &(1<<(($2)&31)))!=0)'); @@ -1591,7 +1606,7 @@ var a, b, i: TLoc; ts: string; begin - setType := skipVarGeneric(e.sons[1].Typ); + setType := skipTypes(e.sons[1].Typ, abstractVar); size := int(getSize(setType)); case size of 1, 2, 4, 8: begin @@ -1676,7 +1691,7 @@ var a: TLoc; begin InitLocExpr(p, e.sons[1], a); - if (skipGenericRange(e.typ).kind in ValueTypes) + if (skipTypes(e.typ, abstractRange).kind in ValueTypes) and not (lfIndirect in a.flags) then putIntoDest(p, d, e.typ, ropef('(*($1*) ($2))', [getTypeDesc(p.module, e.typ), addrLoc(a)])) @@ -1690,7 +1705,7 @@ var a: TLoc; dest: PType; begin - dest := skipVarGeneric(n.typ); + dest := skipTypes(n.typ, abstractVar); if not (optRangeCheck in p.options) then begin InitLocExpr(p, n.sons[0], a); putIntoDest(p, d, n.typ, ropef('(($1) ($2))', @@ -1720,8 +1735,8 @@ var begin while n.sons[0].kind = nkPassAsOpenArray do n.sons[0] := n.sons[0].sons[0]; // BUGFIX - dest := skipVarGeneric(n.typ); - case skipVarGeneric(n.sons[0].typ).kind of + dest := skipTypes(n.typ, abstractVar); + case skipTypes(n.sons[0].typ, abstractVar).kind of tyOpenArray: begin initLocExpr(p, n.sons[0], a); putIntoDest(p, d, dest, ropef('$1, $1Len0', [rdLoc(a)])); @@ -1744,7 +1759,8 @@ var a: TLoc; begin initLocExpr(p, n.sons[0], a); - putIntoDest(p, d, skipVarGeneric(n.typ), ropef('$1->data', [rdLoc(a)])); + putIntoDest(p, d, skipTypes(n.typ, abstractVar), + ropef('$1->data', [rdLoc(a)])); end; procedure convCStrToStr(p: BProc; n: PNode; var d: TLoc); @@ -1753,7 +1769,7 @@ var begin useMagic(p.module, 'cstrToNimstr'); initLocExpr(p, n.sons[0], a); - putIntoDest(p, d, skipVarGeneric(n.typ), + putIntoDest(p, d, skipTypes(n.typ, abstractVar), ropef('cstrToNimstr($1)', [rdLoc(a)])); end; @@ -1793,7 +1809,7 @@ begin genTypeInfo(p.module, t.typ), intLiteral(sonsLen(t))]); genAssignment(p, d, newSeq, {@set}[afSrcIsNotNil]); for i := 0 to sonsLen(t)-1 do begin - initLoc(arr, locExpr, elemType(skipGeneric(t.typ)), OnHeap); + initLoc(arr, locExpr, elemType(skipTypes(t.typ, abstractInst)), OnHeap); arr.r := ropef('$1->data[$2]', [rdLoc(d), intLiteral(i)]); arr.s := OnHeap; // we know that sequences are on the heap expr(p, t.sons[i], arr) @@ -1821,10 +1837,10 @@ begin genAssignment(p, d, newSeq, {@set}[afSrcIsNotNil]); initLocExpr(p, t.sons[1], a); for i := 0 to L-1 do begin - initLoc(elem, locExpr, elemType(skipGeneric(t.typ)), OnHeap); + initLoc(elem, locExpr, elemType(skipTypes(t.typ, abstractInst)), OnHeap); elem.r := ropef('$1->data[$2]', [rdLoc(d), intLiteral(i)]); elem.s := OnHeap; // we know that sequences are on the heap - initLoc(arr, locExpr, elemType(skipGeneric(t.sons[1].typ)), a.s); + initLoc(arr, locExpr, elemType(skipTypes(t.sons[1].typ, abstractInst)), a.s); arr.r := ropef('$1[$2]', [rdLoc(a), intLiteral(i)]); genAssignment(p, elem, arr, {@set}[afDestIsNil, needToCopy]); end @@ -1841,12 +1857,7 @@ begin mUnaryMinusI..mAbsI64: unaryArithOverflow(p, e, d, op); mShrI..mXor: binaryArith(p, e, d, op); mAddi..mModi64: binaryArithOverflow(p, e, d, op); - mRepr: genRepr(p, e, d); - mAsgn: begin - InitLocExpr(p, e.sons[1], a); - assert(a.t <> nil); - expr(p, e.sons[2], a); - end; + mRepr: genRepr(p, e, d); mSwap: genSwap(p, e, d); mPred: begin // XXX: range checking? if not (optOverflowCheck in p.Options) then @@ -1900,7 +1911,7 @@ begin mInc: begin if not (optOverflowCheck in p.Options) then binaryStmt(p, e, d, '', '$1 += $2;$n') - else if skipVarGeneric(e.sons[1].typ).kind = tyInt64 then + else if skipTypes(e.sons[1].typ, abstractVar).kind = tyInt64 then binaryStmt(p, e, d, 'addInt64', '$1 = addInt64($1, $2);$n') else binaryStmt(p, e, d, 'addInt', '$1 = addInt($1, $2);$n') @@ -1908,7 +1919,7 @@ begin ast.mDec: begin if not (optOverflowCheck in p.Options) then binaryStmt(p, e, d, '', '$1 -= $2;$n') - else if skipVarGeneric(e.sons[1].typ).kind = tyInt64 then + else if skipTypes(e.sons[1].typ, abstractVar).kind = tyInt64 then binaryStmt(p, e, d, 'subInt64', '$1 = subInt64($1, $2);$n') else binaryStmt(p, e, d, 'subInt', '$1 = subInt($1, $2);$n') @@ -1919,8 +1930,8 @@ begin mSetLengthSeq: genSetLengthSeq(p, e, d); mIncl, mExcl, mCard, mLtSet, mLeSet, mEqSet, mMulSet, mPlusSet, mMinusSet, mInSet: genSetOp(p, e, d, op); - mNewString, mCopyStr, mCopyStrLast: genCall(p, e, d); - mExit: genCall(p, e, d); + mNewString, mCopyStr, mCopyStrLast, mExit: genCall(p, e, d); + mEcho: genEcho(p, e); mArrToSeq: genArrToSeq(p, e, d); mNLen..mNError: liMessage(e.info, errCannotGenerateCodeForX, e.sons[0].sym.name.s); @@ -2057,7 +2068,7 @@ begin if not handleConstExpr(p, n, d) then begin if d.k = locNone then getTemp(p, n.typ, d); for i := 0 to sonsLen(n)-1 do begin - initLoc(arr, locExpr, elemType(skipGeneric(n.typ)), d.s); + initLoc(arr, locExpr, elemType(skipTypes(n.typ, abstractInst)), d.s); arr.r := ropef('$1[$2]', [rdLoc(d), intLiteral(i)]); expr(p, n.sons[i], arr) end @@ -2087,21 +2098,21 @@ var r, nilCheck: PRope; begin initLocExpr(p, n.sons[0], a); - dest := skipPtrsGeneric(n.typ); + dest := skipTypes(n.typ, abstractPtrs); if (optObjCheck in p.options) and not (isPureObject(dest)) then begin useMagic(p.module, 'chckObj'); r := rdLoc(a); nilCheck := nil; - t := skipGeneric(a.t); + t := skipTypes(a.t, abstractInst); while t.kind in [tyVar, tyPtr, tyRef] do begin if t.kind <> tyVar then nilCheck := r; r := ropef('(*$1)', [r]); - t := skipGeneric(t.sons[0]) + t := skipTypes(t.sons[0], abstractInst) end; if gCmd <> cmdCompileToCpp then while (t.kind = tyObject) and (t.sons[0] <> nil) do begin app(r, '.Sup'); - t := skipGeneric(t.sons[0]); + t := skipTypes(t.sons[0], abstractInst); end; if nilCheck <> nil then appf(p.s[cpsStmts], 'if ($1) chckObj($2.m_type, $3);$n', @@ -2128,11 +2139,12 @@ begin if gCmd = cmdCompileToCpp then expr(p, n.sons[0], d) // downcast does C++ for us else begin - dest := skipPtrsGeneric(n.typ); - src := skipPtrsGeneric(n.sons[0].typ); + dest := skipTypes(n.typ, abstractPtrs); + src := skipTypes(n.sons[0].typ, abstractPtrs); initLocExpr(p, n.sons[0], a); r := rdLoc(a); - if skipGeneric(n.sons[0].typ).kind in [tyRef, tyPtr, tyVar] then begin + if skipTypes(n.sons[0].typ, abstractInst).kind in [tyRef, tyPtr, tyVar] + then begin app(r, '->Sup'); for i := 2 to abs(inheritanceDiff(dest, src)) do app(r, '.Sup'); r := con('&'+'', r); @@ -2201,7 +2213,7 @@ begin end; nkCurly: genSetConstr(p, e, d); nkBracket: - if (skipVarGenericRange(e.typ).kind = tySequence) then // BUGFIX + if (skipTypes(e.typ, abstractVarRange).kind = tySequence) then genSeqConstr(p, e, d) else genArrayConstr(p, e, d); @@ -2211,8 +2223,9 @@ begin nkHiddenStdConv, nkHiddenSubConv, nkConv: genConv(p, e, d); nkHiddenAddr, nkAddr: genAddr(p, e, d); nkBracketExpr: begin - ty := skipVarGenericRange(e.sons[0].typ); - if ty.kind in [tyRef, tyPtr] then ty := skipVarGenericRange(ty.sons[0]); + ty := skipTypes(e.sons[0].typ, abstractVarRange); + if ty.kind in [tyRef, tyPtr] then + ty := skipTypes(ty.sons[0], abstractVarRange); case ty.kind of tyArray, tyArrayConstr: genArrayElem(p, e, d); tyOpenArray: genOpenArrayElem(p, e, d); @@ -2253,7 +2266,7 @@ var begin result := copyNode(n); newSons(result, sonsLen(n)); - t := getUniqueType(skipVarGenericRange(n.Typ)); + t := getUniqueType(skipTypes(n.Typ, abstractVarRange)); if t.n = nil then InternalError(n.info, 'transformRecordExpr: invalid type'); for i := 0 to sonsLen(n)-1 do begin diff --git a/nim/ccgstmts.pas b/nim/ccgstmts.pas index 6cff9dc8d..90e5c1c77 100644 --- a/nim/ccgstmts.pas +++ b/nim/ccgstmts.pas @@ -68,8 +68,8 @@ procedure initVariable(p: BProc; v: PSym); begin if containsGarbageCollectedRef(v.typ) or (v.ast = nil) then // Language change: always initialize variables if v.ast == nil! - if not (skipVarGenericRange(v.typ).Kind in [tyArray, tyArrayConstr, tySet, - tyTuple, tyObject]) then begin + if not (skipTypes(v.typ, abstractVarRange).Kind in [tyArray, + tyArrayConstr, tySet, tyTuple, tyObject]) then begin if gCmd = cmdCompileToLLVM then appf(p.s[cpsStmts], 'store $2 0, $2* $1$n', [addrLoc(v.loc), getTypeDesc(p.module, v.loc.t)]) @@ -618,7 +618,7 @@ end; procedure genCaseStmt(p: BProc; t: PNode); begin genLineDir(p, t); - case skipVarGenericRange(t.sons[0].typ).kind of + case skipTypes(t.sons[0].typ, abstractVarRange).kind of tyString: genStringCase(p, t); tyFloat..tyFloat128: genCaseGeneric(p, t, 'if ($1 >= $2 && $1 <= $3) goto $4;$n', diff --git a/nim/ccgtypes.pas b/nim/ccgtypes.pas index 28db6e009..f9b3a36c1 100644 --- a/nim/ccgtypes.pas +++ b/nim/ccgtypes.pas @@ -62,7 +62,7 @@ begin app(result, toRope(s.id)); if optGenMapping in gGlobalOptions then if s.owner <> nil then - appf(gMapping, '"$1.$2": $3$n', + appf(gMapping, 'r"$1.$2": $3$n', [toRope(s.owner.Name.s), toRope(s.name.s), result]); s.loc.r := result; end @@ -116,8 +116,9 @@ begin end; tyOpenArray, tyArrayConstr, tyArray: result := ctArray; tyObject, tyTuple: result := ctStruct; - tyGeneric, tyGenericInst, tyGenericParam: result := mapType(lastSon(typ)); - tyEnum, tyAnyEnum: begin + tyGeneric, tyGenericInst, tyGenericParam, tyAbstract, tyOrdinal: + result := mapType(lastSon(typ)); + tyEnum: begin if firstOrd(typ) < 0 then result := ctInt32 else begin @@ -150,7 +151,7 @@ end; function mapReturnType(typ: PType): TCTypeKind; begin - if skipGeneric(typ).kind = tyArray then result := ctPtr + if skipTypes(typ, abstractInst).kind = tyArray then result := ctPtr else result := mapType(typ) end; @@ -173,8 +174,9 @@ begin else begin case mapType(rettype) of ctArray: - result := not (skipGeneric(rettype).kind in [tyVar, tyRef, tyPtr]); - ctStruct: result := needsComplexAssignment(skipGeneric(rettype)); + result := not (skipTypes(rettype, abstractInst).kind in [tyVar, tyRef, tyPtr]); + ctStruct: + result := needsComplexAssignment(skipTypes(rettype, abstractInst)); else result := false; end end @@ -285,7 +287,6 @@ begin if (t.sons[0] <> nil) and isInvalidReturnType(t.sons[0]) then begin if params <> nil then app(params, ', '); arr := t.sons[0]; - //if skipGeneric(arr).kind = tyArray then arr := arr.sons[1]; app(params, getTypeDescAux(m, arr, check)); if (mapReturnType(t.sons[0]) <> ctArray) or (gCmd = cmdCompileToLLVM) then app(params, '*'+''); @@ -612,7 +613,7 @@ begin IdTablePut(m.typeCache, t, con(result, '*'+'')); if not isImportedType(t) then begin useMagic(m, 'TGenericSeq'); - if skipGeneric(t.sons[0]).kind <> tyEmpty then + if skipTypes(t.sons[0], abstractInst).kind <> tyEmpty then appf(m.s[cfsSeqTypes], 'struct $2 {$n' + ' TGenericSeq Sup;$n' + @@ -663,7 +664,8 @@ begin end end end; - tyGenericInst: result := getTypeDescAux(m, lastSon(t), check); + tyGenericInst, tyAbstract, tyOrdinal: + result := getTypeDescAux(m, lastSon(t), check); else begin InternalError('getTypeDescAux(' + typeKindToStr[t.kind] + ')'); result := nil diff --git a/nim/ccgutils.pas b/nim/ccgutils.pas index 49c1a8cee..de5cac13c 100644 --- a/nim/ccgutils.pas +++ b/nim/ccgutils.pas @@ -1,7 +1,7 @@ // // // The Nimrod Compiler -// (c) Copyright 2008 Andreas Rumpf +// (c) Copyright 2009 Andreas Rumpf // // See the file "copying.txt", included in this // distribution, for details about the copyright. @@ -56,7 +56,8 @@ begin result := key; end end; - tyGenericInst: result := GetUniqueType(lastSon(key)); + tyGenericInst, tyAbstract, tyOrdinal: + result := GetUniqueType(lastSon(key)); tyProc: begin end; else begin // we have to do a slow linear search because types may need @@ -75,7 +76,7 @@ begin tyInt..tyFloat128, tyProc, tyAnyEnum: begin end; tyNone, tyForward: InternalError('GetUniqueType: ' + typeToString(key)); - tyGenericParam, tyGeneric, tySequence, + tyGenericParam, tyGeneric, tyAbstract, tySequence, tyOpenArray, tySet, tyVar, tyRef, tyPtr, tyArrayConstr, tyArray, tyTuple, tyRange: begin // we have to do a slow linear search because types may need @@ -94,7 +95,7 @@ begin result := key; end end; - tyGenericInst: result := GetUniqueType(lastSon(key)); + tyGenericInst, tyAbstract: result := GetUniqueType(lastSon(key)); end; *) end; diff --git a/nim/cgen.pas b/nim/cgen.pas index 6a0ab0390..fdae6feb6 100644 --- a/nim/cgen.pas +++ b/nim/cgen.pas @@ -1,7 +1,7 @@ // // // The Nimrod Compiler -// (c) Copyright 2008 Andreas Rumpf +// (c) Copyright 2009 Andreas Rumpf // // See the file "copying.txt", included in this // distribution, for details about the copyright. @@ -232,8 +232,8 @@ end; function isSimpleConst(typ: PType): bool; begin - result := not (skipVarGeneric(typ).kind in [tyTuple, tyObject, tyArray, - tyArrayConstr, tySet, tySequence]) + result := not (skipTypes(typ, abstractVar).kind in [tyTuple, tyObject, + tyArray, tyArrayConstr, tySet, tySequence]) end; procedure useHeader(m: BModule; sym: PSym); @@ -249,12 +249,6 @@ procedure UseMagic(m: BModule; const name: string); forward; {$include 'ccgtypes.pas'} // ------------------------------ Manager of temporaries ------------------ -(* -function beEqualTypes(a, b: PType): bool; -begin - // returns whether two type are equal for the backend - result := sameType(skipGenericRange(a), skipGenericRange(b)) -end; *) procedure getTemp(p: BProc; t: PType; var result: TLoc); begin @@ -458,9 +452,35 @@ procedure genProcPrototype(m: BModule; sym: PSym); forward; // We don't finalize dynamic libs as this does the OS for us. +procedure libCandidates(const s: string; var dest: TStringSeq); +var + prefix, suffix: string; + le, ri, i, L: int; + temp: TStringSeq; +begin + le := strutils.find(s, '('); + ri := strutils.find(s, ')'); + if (le >= strStart) and (ri > le) then begin + prefix := ncopy(s, strStart, le-1); + suffix := ncopy(s, ri+1); + temp := splitSeq(ncopy(s, le+1, ri-1), {@set}['|']); + for i := 0 to high(temp) do + libCandidates(prefix +{&} temp[i] +{&} suffix, dest); + end + else begin + {@ignore} + L := length(dest); + setLength(dest, L+1); + dest[L] := s; + {@emit add(dest, s);} + end +end; + procedure loadDynamicLib(m: BModule; lib: PLib); var - tmp: PRope; + tmp, loadlib: PRope; + s: TStringSeq; + i: int; begin assert(lib <> nil); if not lib.generated then begin @@ -471,18 +491,29 @@ begin // BUGFIX: useMagic has awful side-effects appff(m.s[cfsVars], 'static void* $1;$n', '$1 = linkonce global i8* zeroinitializer$n', [tmp]); - inc(m.labels); - appff(m.s[cfsDynLibInit], - '$1 = nimLoadLibrary((NimStringDesc*) &$2);$n', - '%MOC$4 = call i8* @nimLoadLibrary($3 $2)$n' + - 'store i8* %MOC$4, i8** $1$n', - [tmp, getStrLit(m, lib.path), getTypeDesc(m, getSysType(tyString)), - toRope(m.labels)]); + {@ignore} s := nil; {@emit s := @[];} + libCandidates(lib.path, s); + loadlib := nil; + for i := 0 to high(s) do begin + inc(m.labels); + if i > 0 then app(loadlib, '||'); + appff(loadlib, + '($1 = nimLoadLibrary((NimStringDesc*) &$2))$n', + '%MOC$4 = call i8* @nimLoadLibrary($3 $2)$n' + + 'store i8* %MOC$4, i8** $1$n', + [tmp, getStrLit(m, s[i]), getTypeDesc(m, getSysType(tyString)), + toRope(m.labels)]); + end; + appff(m.s[cfsDynLibInit], + 'if (!($1)) nimLoadLibraryError((NimStringDesc*) &$2);$n', + 'XXX too implement', + [loadlib, getStrLit(m, lib.path)]); //appf(m.s[cfsDynLibDeinit], // 'if ($1 != NIM_NIL) nimUnloadLibrary($1);$n', [tmp]); useMagic(m, 'nimLoadLibrary'); useMagic(m, 'nimUnloadLibrary'); useMagic(m, 'NimStringDesc'); + useMagic(m, 'nimLoadLibraryError'); end; if lib.name = nil then InternalError('loadDynamicLib'); end; @@ -642,7 +673,7 @@ begin else begin fillResult(res); assignParam(p, res); - if skipGeneric(res.typ).kind = tyArray then begin + if skipTypes(res.typ, abstractInst).kind = tyArray then begin include(res.loc.flags, lfIndirect); res.loc.s := OnUnknown; end; @@ -745,6 +776,7 @@ end; procedure genProc(m: BModule; prc: PSym); begin + if sfBorrow in prc.flags then exit; fillProcLoc(prc); if [sfForward, sfFromGeneric] * prc.flags <> [] then addForwardedProc(m, prc) @@ -1148,7 +1180,6 @@ begin addFileToCompile(cfilenoext); end; addFileToLink(cfilenoext); - if sfMainModule in m.module.flags then writeMapping(cfile, gMapping); end; function myClose(b: PPassContext; n: PNode): PNode; @@ -1177,6 +1208,7 @@ begin finishModule(gPendingModules[i]); for i := 0 to high(gPendingModules) do writeModule(gPendingModules[i]); setLength(gPendingModules, 0); + writeMapping(gMapping); end; if not (optDeadCodeElim in gGlobalOptions) and not (sfDeadCodeElim in m.module.flags) then diff --git a/nim/commands.pas b/nim/commands.pas index fde2d26c7..df6ab9da7 100644 --- a/nim/commands.pas +++ b/nim/commands.pas @@ -150,7 +150,8 @@ begin if (pass = passCmd1) and not helpWritten then begin // BUGFIX 19 MessageOut(getCommandLineDesc()); - helpWritten := true + helpWritten := true; + halt(0); end end; diff --git a/nim/condsyms.pas b/nim/condsyms.pas index 1df513bbc..465bc045e 100644 --- a/nim/condsyms.pas +++ b/nim/condsyms.pas @@ -111,8 +111,7 @@ begin DefineSymbol('mswindows'); DefineSymbol('win32'); end; - osLinux, osMorphOS, osSkyOS, osIrix, osPalmOS, osQNX, - osAtari, osAix: begin + osLinux, osMorphOS, osSkyOS, osIrix, osPalmOS, osQNX, osAtari, osAix: begin // these are all 'unix-like' DefineSymbol('unix'); DefineSymbol('posix'); diff --git a/nim/docgen.pas b/nim/docgen.pas index 784ab6c6c..5e8ecf7a3 100644 --- a/nim/docgen.pas +++ b/nim/docgen.pas @@ -235,6 +235,8 @@ begin end; function toXml(const s: string; splitAfter: int = -1): string; +const + splitter = '<wbr />'; var i, j, k, partLen: int; begin @@ -244,9 +246,9 @@ begin j := strStart; while j < length(s)+strStart do begin k := nextSplitPoint(s, j); - if partLen + k - j + 1 > splitAfter then begin + if (splitter <> ' '+'') or (partLen + k - j + 1 > splitAfter) then begin partLen := 0; - addChar(result, ' '); + add(result, splitter); end; for i := j to k do addXmlChar(result, s[i]); inc(partLen, k - j + 1); @@ -691,9 +693,10 @@ var langstr: string; lang: TSourceLanguage; begin + result := nil; + if n.sons[2] = nil then exit; m := n.sons[2].sons[0]; if (m.kind <> rnLeaf) then InternalError('renderCodeBlock'); - result := nil; langstr := strip(getArgument(n)); if langstr = '' then lang := langNimrod // default language else lang := getSourceLanguage(langstr); @@ -996,7 +999,6 @@ begin rst := rstParse(readFile(filen), false, filen, 0, 1, d.hasToc); d.modDesc := renderRstToHtml(d, rst); code := genHtmlFile(d); - assert(ropeInvariant(code)); writeRope(code, getOutFile(filename, HtmlExt)); generateIndex(d); end; diff --git a/nim/ecmasgen.pas b/nim/ecmasgen.pas index 2eecfba71..9ffa550ae 100644 --- a/nim/ecmasgen.pas +++ b/nim/ecmasgen.pas @@ -109,7 +109,7 @@ const function mapType(typ: PType): TEcmasTypeKind; begin - case skipGeneric(typ).kind of + case skipTypes(typ, abstractInst).kind of tyVar, tyRef, tyPtr: begin if typ.sons[0].kind in mappedToObject then result := etyObject @@ -120,8 +120,8 @@ begin // treat a tyPointer like a typed pointer to an array of bytes result := etyInt; end; - tyRange: result := mapType(typ.sons[0]); - tyInt..tyInt64, tyEnum, tyAnyEnum, tyChar: + tyRange, tyAbstract, tyOrdinal: result := mapType(typ.sons[0]); + tyInt..tyInt64, tyEnum, tyChar: result := etyInt; tyBool: result := etyBool; tyFloat..tyFloat128: result := etyFloat; @@ -298,7 +298,8 @@ begin if t.kind = tyGenericInst then t := lastSon(t); result := ropef('NTI$1', [toRope(t.id)]); if IntSetContainsOrIncl(p.globals.TypeInfoGenerated, t.id) then exit; - case t.kind of + case t.kind of + tyAbstract: result := genTypeInfo(p, typ.sons[0]); tyPointer, tyProc, tyBool, tyChar, tyCString, tyString, tyInt..tyFloat128: begin s := ropef( @@ -676,7 +677,7 @@ begin if n.sons[0] <> nil then begin gen(p, n.sons[0], a); if a.com <> nil then appf(r.com, '$1;$n', [a.com]); - typ := skipPtrsGeneric(n.sons[0].typ); + typ := skipTypes(n.sons[0].typ, abstractPtrs); useMagic(p, 'raiseException'); appf(r.com, 'raiseException($1, $2);$n', [a.res, makeCString(typ.sym.name.s)]); @@ -698,7 +699,7 @@ begin gen(p, n.sons[0], cond); if cond.com <> nil then appf(r.com, '$1;$n', [cond.com]); - stringSwitch := skipVarGeneric(n.sons[0].typ).kind = tyString; + stringSwitch := skipTypes(n.sons[0].typ, abstractVar).kind = tyString; if stringSwitch then begin useMagic(p, 'toEcmaStr'); appf(r.com, 'switch (toEcmaStr($1)) {$n', [cond.res]) @@ -888,12 +889,12 @@ const nkFloatLit..nkFloat64Lit, nkCurly, nkPar, nkStringToCString, nkCStringToString, - nkCall, nkHiddenCallConv]; + nkCall, nkCommand, nkHiddenCallConv]; function needsNoCopy(y: PNode): bool; begin result := (y.kind in nodeKindsNeedNoCopy) - or (skipGeneric(y.typ).kind in [tyRef, tyPtr, tyVar]) + or (skipTypes(y.typ, abstractInst).kind in [tyRef, tyPtr, tyVar]) end; procedure genAsgnAux(var p: TProc; x, y: PNode; var r: TCompRes; @@ -1014,7 +1015,7 @@ begin gen(p, n.sons[0], a); gen(p, n.sons[1], b); r.com := mergeExpr(a); - typ := skipPtrsGeneric(n.sons[0].typ); + typ := skipTypes(n.sons[0].typ, abstractPtrs); if typ.kind in [tyArray, tyArrayConstr] then first := FirstOrd(typ.sons[0]) else first := 0; if (optBoundsCheck in p.options) and not isConstExpr(n.sons[1]) then begin @@ -1201,9 +1202,9 @@ var i, len, c: int; t, e: PType; begin - t := skipGeneric(typ); + t := skipTypes(typ, abstractInst); case t.kind of - tyInt..tyInt64, tyEnum, tyAnyEnum, tyChar: begin + tyInt..tyInt64, tyEnum, tyChar: begin result := putToSeq('0'+'', indirect) end; tyFloat..tyFloat128: result := putToSeq('0.0', indirect); @@ -1354,15 +1355,15 @@ var t: Ptype; begin gen(p, n.sons[1], a); - t := skipVarGeneric(n.sons[1].typ).sons[0]; + t := skipTypes(n.sons[1].typ, abstractVar).sons[0]; if a.com <> nil then appf(r.com, '$1;$n', [a.com]); appf(r.com, '$1 = $2;$n', [a.res, createVar(p, t, true)]); end; procedure genOrd(var p: TProc; n: PNode; var r: TCompRes); begin - case skipVarGeneric(n.sons[1].typ).kind of - tyEnum, tyAnyEnum, tyInt..tyInt64, tyChar: gen(p, n.sons[1], r); + case skipTypes(n.sons[1].typ, abstractVar).kind of + tyEnum, tyInt..tyInt64, tyChar: gen(p, n.sons[1], r); tyBool: unaryExpr(p, n, r, '', '($1 ? 1:0)'); else InternalError(n.info, 'genOrd'); end @@ -1375,9 +1376,9 @@ begin gen(p, n.sons[1], a); gen(p, n.sons[2], b); r.com := mergeExpr(a.com, b.com); - if skipVarGenericRange(n.sons[1].typ).kind = tyChar then + if skipTypes(n.sons[1].typ, abstractVarRange).kind = tyChar then a.res := ropef('[$1, 0]', [a.res]); - if skipVarGenericRange(n.sons[2].typ).kind = tyChar then + if skipTypes(n.sons[2].typ, abstractVarRange).kind = tyChar then b.res := ropef('[$1, 0]', [b.res]); r.res := ropef('($1.slice(0,-1)).concat($2)', [a.res, b.res]); end; @@ -1435,7 +1436,7 @@ begin mLengthSeq, mLengthOpenArray, mLengthArray: unaryExpr(p, n, r, '', '$1.length'); mHigh: begin - if skipVarGeneric(n.sons[0].typ).kind = tyString then + if skipTypes(n.sons[0].typ, abstractVar).kind = tyString then unaryExpr(p, n, r, '', '($1.length-2)') else unaryExpr(p, n, r, '', '($1.length-1)'); @@ -1535,8 +1536,8 @@ procedure genConv(var p: TProc; n: PNode; var r: TCompRes); var src, dest: PType; begin - dest := skipVarGenericRange(n.typ); - src := skipVarGenericRange(n.sons[1].typ); + dest := skipTypes(n.typ, abstractVarRange); + src := skipTypes(n.sons[1].typ, abstractVarRange); gen(p, n.sons[1], r); if (dest.kind <> src.kind) and (src.kind = tyBool) then r.res := ropef('(($1)? 1:0)', [r.res]) @@ -1750,7 +1751,7 @@ begin r.res := toRope('null'); end; nkStrLit..nkTripleStrLit: begin - if skipVarGenericRange(n.typ).kind = tyString then begin + if skipTypes(n.typ, abstractVarRange).kind = tyString then begin useMagic(p, 'cstrToNimstr'); r.res := ropef('cstrToNimstr($1)', [makeCString(n.strVal)]) end @@ -1771,7 +1772,7 @@ begin end; nkBlockExpr: genBlock(p, n, r); nkIfExpr: genIfExpr(p, n, r); - nkCall, nkHiddenCallConv: begin + nkCall, nkHiddenCallConv, nkCommand: begin if (n.sons[0].kind = nkSym) and (n.sons[0].sym.magic <> mNone) then genMagic(p, n, r) else diff --git a/nim/evals.pas b/nim/evals.pas index 218046c7e..7c443bad6 100644 --- a/nim/evals.pas +++ b/nim/evals.pas @@ -27,10 +27,10 @@ type PStackFrame = ^TStackFrame; TStackFrame = record mapping: TIdNodeTable; // mapping from symbols to nodes - prc: PSym; // current prc; proc that is evaluated + prc: PSym; // current prc; proc that is evaluated call: PNode; - next: PStackFrame; // for stacking - params: TNodeSeq; // parameters passed to the proc + next: PStackFrame; // for stacking + params: TNodeSeq; // parameters passed to the proc end; TEvalContext = object(passes.TPassContext) @@ -264,7 +264,7 @@ var i: int; t: PType; begin - t := skipGenericRange(typ); + t := skipTypes(typ, abstractRange); result := emptyNode; case t.kind of tyBool, tyChar, tyInt..tyInt64: result := newNodeIT(nkIntLit, info, t); @@ -527,6 +527,27 @@ begin result := emptyNode end; +function getStrValue(n: PNode): string; +begin + case n.kind of + nkStrLit..nkTripleStrLit: result := n.strVal; + else begin InternalError(n.info, 'getStrValue'); result := '' end; + end +end; + +function evalEcho(c: PEvalContext; n: PNode): PNode; +var + i: int; +begin + for i := 1 to sonsLen(n)-1 do begin + result := evalAux(c, n.sons[i]); + if result.kind = nkExceptBranch then exit; + Write(output, getStrValue(result)); + end; + writeln(output, ''); + result := emptyNode +end; + function evalExit(c: PEvalContext; n: PNode): PNode; begin result := evalAux(c, n.sons[1]); @@ -555,7 +576,7 @@ function evalNew(c: PEvalContext; n: PNode): PNode; var t: PType; begin - t := skipVarGeneric(n.sons[1].typ); + t := skipTypes(n.sons[1].typ, abstractVar); result := newNodeIT(nkRefTy, n.info, t); addSon(result, getNullValue(t.sons[0], n.info)); end; @@ -604,8 +625,8 @@ var begin result := evalAux(c, n.sons[0]); if result.kind = nkExceptBranch then exit; - dest := skipPtrsGeneric(n.typ); - src := skipPtrsGeneric(result.typ); + dest := skipTypes(n.typ, abstractPtrs); + src := skipTypes(result.typ, abstractPtrs); if inheritanceDiff(src, dest) > 0 then stackTrace(c, n, errInvalidConversionFromTypeX, typeToString(src)); end; @@ -700,7 +721,7 @@ function evalHigh(c: PEvalContext; n: PNode): PNode; begin result := evalAux(c, n.sons[1]); if result.kind = nkExceptBranch then exit; - case skipVarGeneric(n.sons[1].typ).kind of + case skipTypes(n.sons[1].typ, abstractVar).kind of tyOpenArray, tySequence: result := newIntNodeT(sonsLen(result), n); tyString: @@ -749,7 +770,7 @@ begin oldLen := sonsLen(a); setLength(a.sons, newLen); for i := oldLen to newLen-1 do - a.sons[i] := getNullValue(skipVarGeneric(n.sons[1].typ), n.info); + a.sons[i] := getNullValue(skipTypes(n.sons[1].typ, abstractVar), n.info); result := emptyNode end; @@ -766,7 +787,7 @@ begin if result.kind = nkExceptBranch then exit; b := result; - t := skipVarGeneric(n.sons[1].typ); + t := skipTypes(n.sons[1].typ, abstractVar); if a.kind = nkEmpty then InternalError(n.info, 'first parameter is empty'); a.kind := nkBracket; a.info := n.info; @@ -835,14 +856,6 @@ begin result := emptyNode; end; -function getStrValue(n: PNode): string; -begin - case n.kind of - nkStrLit..nkTripleStrLit: result := n.strVal; - else begin InternalError(n.info, 'getStrValue'); result := '' end; - end -end; - function evalConStrStr(c: PEvalContext; n: PNode): PNode; // we cannot use ``evalOp`` for this as we can here have more than 2 arguments var @@ -936,6 +949,7 @@ begin mSwap: result := evalSwap(c, n); mInc: result := evalIncDec(c, n, 1); ast.mDec: result := evalIncDec(c, n, -1); + mEcho: result := evalEcho(c, n); mSetLengthStr: result := evalSetLengthStr(c, n); mSetLengthSeq: result := evalSetLengthSeq(c, n); mIncl: result := evalIncl(c, n); @@ -1237,7 +1251,8 @@ begin nkType..pred(nkNilLit): result := copyNode(n); nkNilLit: result := n; // end of atoms - nkCall, nkHiddenCallConv, nkMacroStmt: result := evalMagicOrCall(c, n); + nkCall, nkHiddenCallConv, nkMacroStmt, nkCommand: + result := evalMagicOrCall(c, n); nkCurly, nkBracket, nkRange: begin result := copyNode(n); for i := 0 to sonsLen(n)-1 do addSon(result, evalAux(c, n.sons[i])); diff --git a/nim/extccomp.pas b/nim/extccomp.pas index a53ad1c10..a3e4ff367 100644 --- a/nim/extccomp.pas +++ b/nim/extccomp.pas @@ -288,7 +288,7 @@ function NameToCC(const name: string): TSystemCC; procedure initVars; procedure setCC(const ccname: string); -procedure writeMapping(const cfile: string; gSymbolMapping: PRope); +procedure writeMapping(gSymbolMapping: PRope); implementation @@ -638,12 +638,12 @@ begin result := nil; it := PStrEntry(list.head); while it <> nil do begin - appf(result, '--file:"$1"$n', [toRope(AppendFileExt(it.data, cExt))]); + appf(result, '--file:r"$1"$n', [toRope(AppendFileExt(it.data, cExt))]); it := PStrEntry(it.next); end; end; -procedure writeMapping(const cfile: string; gSymbolMapping: PRope); +procedure writeMapping(gSymbolMapping: PRope); var code: PRope; begin diff --git a/nim/magicsys.pas b/nim/magicsys.pas index 462912995..db801d5f2 100644 --- a/nim/magicsys.pas +++ b/nim/magicsys.pas @@ -76,7 +76,6 @@ begin tyString: result := sysTypeFromName('string'); tyCstring: result := sysTypeFromName('cstring'); tyPointer: result := sysTypeFromName('pointer'); - tyAnyEnum: result := newSysType(tyAnyEnum, 1); tyNil: result := newSysType(tyNil, ptrSize); else InternalError('request for typekind: ' + typeKindToStr[kind]); end; diff --git a/nim/msgs.pas b/nim/msgs.pas index d7f0d9f82..48ffc9ee5 100644 --- a/nim/msgs.pas +++ b/nim/msgs.pas @@ -49,557 +49,557 @@ uses //cog.out(warns) //cog.out(hints) //]]] -type - TMsgKind = ( - errUnknown, - errIllFormedAstX, - errCannotOpenFile, - errInternal, - errGenerated, - errXCompilerDoesNotSupportCpp, - errStringLiteralExpected, - errIntLiteralExpected, - errInvalidCharacterConstant, - errClosingTripleQuoteExpected, - errClosingQuoteExpected, - errTabulatorsAreNotAllowed, - errInvalidToken, - errLineTooLong, - errInvalidNumber, - errNumberOutOfRange, - errNnotAllowedInCharacter, - errClosingBracketExpected, - errMissingFinalQuote, - errIdentifierExpected, - errOperatorExpected, - errTokenExpected, - errStringAfterIncludeExpected, - errRecursiveInclude, - errOnOrOffExpected, - errNoneSpeedOrSizeExpected, - errInvalidPragma, - errUnknownPragma, - errPragmaXHereNotAllowed, - errUnknownDirective, - errInvalidDirective, - errAtPopWithoutPush, - errEmptyAsm, - errAsgnInvalidInExpr, - errInvalidIndentation, - errExceptionExpected, - errExceptionAlreadyHandled, - errReturnNotAllowedHere, - errYieldNotAllowedHere, - errInvalidNumberOfYieldExpr, - errReturnInvalidInIterator, - errCannotReturnExpr, - errAttemptToRedefine, - errStmtInvalidAfterReturn, - errStmtExpected, - errInvalidLabel, - errInvalidCmdLineOption, - errCmdLineArgExpected, - errCmdLineNoArgExpected, - errInvalidVarSubstitution, - errUnknownVar, - errUnknownCcompiler, - errOnOrOffExpectedButXFound, - errNoneBoehmRefcExpectedButXFound, - errNoneSpeedOrSizeExpectedButXFound, - errGuiConsoleOrLibExpectedButXFound, - errUnknownOS, - errUnknownCPU, - errGenOutExpectedButXFound, - errArgsNeedRunOption, - errInvalidMultipleAsgn, - errColonOrEqualsExpected, - errExprExpected, - errUndeclaredIdentifier, - errUseQualifier, - errTwiceForwarded, - errTypeExpected, - errSystemNeeds, - errExecutionOfProgramFailed, - errNotOverloadable, - errInvalidArgForX, - errStmtHasNoEffect, - errXExpectsTypeOrValue, - errXExpectsArrayType, - errIteratorCannotBeInstantiated, - errExprWithNoTypeCannotBeConverted, - errExprWithNoTypeCannotBeCasted, - errConstantDivisionByZero, - errOrdinalTypeExpected, - errOrdinalOrFloatTypeExpected, - errOverOrUnderflow, - errCannotEvalXBecauseIncompletelyDefined, - errChrExpectsRange0_255, - errStaticAssertFailed, - errStaticAssertCannotBeEval, - errDotRequiresRecordOrObjectType, - errUndeclaredFieldX, - errNilAccess, - errIndexOutOfBounds, - errIndexTypesDoNotMatch, - errBracketsInvalidForType, - errValueOutOfSetBounds, - errFieldInitTwice, - errFieldNotInit, - errExprCannotBeCalled, - errExprHasNoType, - errExprXHasNoType, - errCastNotInSafeMode, - errExprCannotBeCastedToX, - errUndefinedPrefixOpr, - errCommaOrParRiExpected, - errCurlyLeOrParLeExpected, - errSectionExpected, - errImplemenationExpected, - errRangeExpected, - errInvalidTypeDescription, - errAttemptToRedefineX, - errMagicOnlyInSystem, - errUnknownOperatorX, - errPowerOfTwoExpected, - errStringMayNotBeEmpty, - errCallConvExpected, - errProcOnlyOneCallConv, - errSymbolMustBeImported, - errExprMustBeBool, - errConstExprExpected, - errDuplicateCaseLabel, - errRangeIsEmpty, - errSelectorMustBeOfCertainTypes, - errSelectorMustBeOrdinal, - errOrdXMustNotBeNegative, - errLenXinvalid, - errWrongNumberOfVariables, - errExprCannotBeRaised, - errBreakOnlyInLoop, - errTypeXhasUnknownSize, - errConstNeedsConstExpr, - errConstNeedsValue, - errResultCannotBeOpenArray, - errSizeTooBig, - errSetTooBig, - errBaseTypeMustBeOrdinal, - errInheritanceOnlyWithNonFinalObjects, - errInheritanceOnlyWithEnums, - errIllegalRecursionInTypeX, - errCannotInstantiateX, - errExprHasNoAddress, - errVarForOutParamNeeded, - errPureTypeMismatch, - errTypeMismatch, - errButExpected, - errButExpectedX, - errAmbigiousCallXYZ, - errWrongNumberOfTypeParams, - errOutParamNoDefaultValue, - errInlineProcHasNoAddress, - errXCannotBeInParamDecl, - errPragmaOnlyInHeaderOfProc, - errImportedProcCannotHaveImpl, - errImplOfXNotAllowed, - errImplOfXexpected, - errDiscardValue, - errInvalidDiscard, - errUnknownPrecedence, - errIllegalConvFromXtoY, - errTypeMismatchExpectedXGotY, - errCannotBindXTwice, - errInvalidOrderInEnumX, - errEnumXHasWholes, - errExceptExpected, - errInvalidTry, - errEofExpectedButXFound, - errOptionExpected, - errCannotEvaluateForwardConst, - errXisNoLabel, - errXNeedsConcreteType, - errNotAllCasesCovered, - errStringRange, - errUnkownSubstitionVar, - errComplexStmtRequiresInd, - errXisNotCallable, - errNoPragmasAllowedForX, - errNoGenericParamsAllowedForX, - errInvalidParamKindX, - errDefaultArgumentInvalid, - errNamedParamHasToBeIdent, - errNoReturnTypeForX, - errConvNeedsOneArg, - errInvalidPragmaX, - errXNotAllowedHere, - errInvalidControlFlowX, - errATypeHasNoValue, - errXisNoType, - errCircumNeedsPointer, - errInvalidContextForBuiltinX, - errInvalidExpression, - errInvalidExpressionX, - errEnumHasNoValueX, - errNamedExprExpected, - errNamedExprNotAllowed, - errXExpectsOneTypeParam, - errArrayExpectsTwoTypeParams, - errInvalidVisibilityX, - errInitHereNotAllowed, - errXCannotBeAssignedTo, - errIteratorNotAllowed, - errIteratorNeedsImplementation, - errIteratorNeedsReturnType, - errInvalidCommandX, - errXOnlyAtModuleScope, - errTypeXNeedsImplementation, - errTemplateInstantiationTooNested, - errInstantiationFrom, - errInvalidIndexValueForTuple, - errCommandExpectsFilename, - errXExpected, - errInvalidSectionStart, - errGridTableNotImplemented, - errGeneralParseError, - errNewSectionExpected, - errWhitespaceExpected, - errXisNoValidIndexFile, - errCannotRenderX, - errVarVarTypeNotAllowed, - errIsExpectsTwoArguments, - errIsExpectsObjectTypes, - errXcanNeverBeOfThisSubtype, - errTooManyIterations, - errCannotInterpretNodeX, - errFieldXNotFound, - errInvalidConversionFromTypeX, - errAssertionFailed, - errCannotGenerateCodeForX, - errXNeedsReturnType, - errXRequiresOneArgument, - errUnhandledExceptionX, - errCyclicTree, - errXisNoMacroOrTemplate, - errUser, - warnCannotOpenFile, - warnOctalEscape, - warnXIsNeverRead, - warnXmightNotBeenInit, - warnCannotWriteMO2, - warnCannotReadMO2, - warnDeprecated, - warnSmallLshouldNotBeUsed, - warnUnknownMagic, - warnRedefinitionOfLabel, - warnUnknownSubstitutionX, - warnLanguageXNotSupported, - warnCommentXIgnored, - warnUser, - hintSuccess, - hintSuccessX, - hintLineTooLong, - hintXDeclaredButNotUsed, - hintConvToBaseNotNeeded, - hintConvFromXtoItselfNotNeeded, - hintExprAlwaysX, - hintQuitCalled, - hintProcessing, - hintCodeBegin, - hintCodeEnd, - hintConf, - hintUser); - -const - MsgKindToStr: array [TMsgKind] of string = ( - 'unknown error', - 'illformed AST: $1', - 'cannot open ''$1''', - 'internal error: $1', - '$1', - '''$1'' compiler does not support C++', - 'string literal expected', - 'integer literal expected', - 'invalid character constant', - 'closing """ expected, but end of file reached', - 'closing " expected', - 'tabulators are not allowed', - 'invalid token: $1', - 'line too long', - '$1 is not a valid number', - 'number $1 out of valid range', - '\n not allowed in character literal', - 'closing '']'' expected, but end of file reached', - 'missing final ''', - 'identifier expected, but found ''$1''', - 'operator expected, but found ''$1''', - '''$1'' expected', - 'string after ''include'' expected', - 'recursive include file: ''$1''', - '''on'' or ''off'' expected', - '''none'', ''speed'' or ''size'' expected', - 'invalid pragma', - 'unknown pragma: ''$1''', - 'pragma ''$1'' here not allowed', - 'unknown directive: ''$1''', - 'invalid directive', - '''pop'' without a ''push'' pragma', - 'empty asm statement makes no sense', - '''='' invalid in an expression; probably ''=='' meant', - 'invalid indentation', - 'exception expected', - 'exception already handled', - '''return'' only allowed in routine', - '''yield'' only allowed in a loop of an iterator', - 'invalid number of ''yield'' expresions', - '''return'' not allowed in iterator', - 'current routine cannot return an expression', - 'attempt to redefine ''$1''', - 'statement not allowed after ''return'', ''break'' or ''raise''', - 'statement expected', - '''$1'' is no label', - 'invalid command line option: ''$1''', - 'argument for command line option expected: ''$1''', - 'invalid argument for command line option: ''$1''', - 'invalid variable substitution in ''$1''', - 'unknown variable: ''$1''', - 'unknown C compiler: ''$1''', - '''on'' or ''off'' expected, but ''$1'' found', - '''none'', ''boehm'' or ''refc'' expected, but ''$1'' found', - '''none'', ''speed'' or ''size'' expected, but ''$1'' found', - '''gui'', ''console'' or ''lib'' expected, but ''$1'' found', - 'unknown OS: ''$1''', - 'unknown CPU: ''$1''', - '''c'', ''c++'' or ''yaml'' expected, but ''$1'' found', - 'arguments can only be given if the ''--run'' option is selected', - 'multiple assignment is not allowed', - ''':'' or ''='' expected, but found ''$1''', - 'expression expected, but found ''$1''', - 'undeclared identifier: ''$1''', - 'ambigious identifier: ''$1'' -- use a qualifier', - '''$1'' is forwarded twice', - 'type expected', - 'system module needs ''$1''', - 'execution of an external program failed', - 'overloaded ''$1'' leads to ambigious calls', - 'invalid argument for ''$1''', - 'statement has no effect', - '''$1'' expects a type or value', - '''$1'' expects an array type', - '''$1'' cannot be instantiated because its body has not been compiled yet', - 'expression with no type cannot be converted', - 'expression with no type cannot be casted', - 'constant division by zero', - 'ordinal type expected', - 'ordinal or float type expected', - 'over- or underflow', - 'cannot evalutate ''$1'' because type is not defined completely', - '''chr'' expects an int in the range 0..255', - '''staticAssert'' failed: condition is false', - 'argument to ''staticAssert'' cannot be evaluated at compile time', - '''.'' requires a record or object type', - 'undeclared field: ''$1''', - 'attempt to access a nil address', - 'index out of bounds', - 'index types do not match', - '''[]'' operator invalid for this type', - 'value out of set bounds', - 'field initialized twice: ''$1''', - 'field ''$1'' not initialized', - 'expression cannot be called', - 'expression has no type', - 'expression ''$1'' has no type', - '''cast'' not allowed in safe mode', - 'expression cannot be casted to $1', - 'undefined prefix operator: $1', - ''','' or '')'' expected', - '''{'' or ''('' expected', - 'section (''type'', ''proc'', etc.) expected', - '''implementation'' or end of file expected', - 'range expected', - 'invalid type description', - 'attempt to redefine ''$1''', - '''magic'' only allowed in system module', - 'unkown operator: ''$1''', - 'power of two expected', - 'string literal may not be empty', - 'calling convention expected', - 'a proc can only have one calling convention', - 'symbol must be imported if ''lib'' pragma is used', - 'expression must be of type ''bool''', - 'constant expression expected', - 'duplicate case label', - 'range is empty', - 'selector must be of an ordinal type, real or string', - 'selector must be of an ordinal type', - 'ord($1) must not be negative', - 'len($1) must be less than 32768', - 'wrong number of variables', - 'only objects can be raised', - '''break'' only allowed in loop construct', - 'type ''$1'' has unknown size', - 'a constant can only be initialized with a constant expression', - 'a constant needs a value', - 'the result type cannot be on open array', - 'computing the type''s size produced an overflow', - 'set is too large', - 'base type of a set must be an ordinal', - 'inheritance only works with non-final objects', - 'inheritance only works with an enum', - 'illegal recursion in type ''$1''', - 'cannot instantiate: ''$1''', - 'expression has no address', - 'for a ''var'' type a variable needs to be passed', - 'type mismatch', - 'type mismatch: got (', - 'but expected one of: ', - 'but expected ''$1''', - 'ambigious call; both $1 and $2 match for: $3', - 'wrong number of type parameters', - 'out parameters cannot have default values', - 'an inline proc has no address', - '$1 cannot be declared in parameter declaration', - 'pragmas are only in the header of a proc allowed', - 'an imported proc cannot have an implementation', - 'implementation of ''$1'' is not allowed here', - 'implementation of ''$1'' expected', - 'value returned by statement has to be discarded', - 'statement returns no value that can be discarded', - 'unknown precedence for operator; use ''infix: prec'' pragma', - 'conversion from $1 to $2 is invalid', - 'type mismatch: expected ''$1'', but got ''$2''', - 'cannot bind parameter ''$1'' twice', - 'invalid order in enum ''$1''', - 'enum ''$1'' has wholes', - '''except'' or ''finally'' expected', - 'after catch all ''except'' or ''finally'' no section may follow', - 'end of file expected, but found token ''$1''', - 'option expected, but found ''$1''', - 'cannot evaluate forwarded constant', - '''$1'' is not a label', - '''$1'' needs to be of a non-generic type', - 'not all cases are covered', - 'string range in case statement not allowed', - 'unknown substitution variable: ''$1''', - 'complex statement requires indentation', - '''$1'' is not callable', - 'no pragmas allowed for $1', - 'no generic parameters allowed for $1', - 'invalid param kind: ''$1''', - 'default argument invalid', - 'named parameter has to be an identifier', - 'no return type for $1 allowed', - 'a type conversion needs exactly one argument', - 'invalid pragma: $1', - '$1 here not allowed', - 'invalid control flow: $1', - 'a type has no value', - 'invalid type: ''$1''', - '''^'' needs a pointer or reference type', - 'invalid context for builtin ''$1''', - 'invalid expression', - 'invalid expression: ''$1''', - 'enum has no value ''$1''', - 'named expression expected', - 'named expression here not allowed', - '''$1'' expects one type parameter', - 'array expects two type parameters', - 'invalid invisibility: ''$1''', - 'initialization here not allowed', - '''$1'' cannot be assigned to', - 'iterators can only be defined at the module''s top level', - 'iterator needs an implementation', - 'iterator needs a return type', - 'invalid command: ''$1''', - '''$1'' is only allowed at top level', - 'type ''$1'' needs an implementation', - 'template instantiation too nested', - 'instantiation from here', - 'invalid index value for tuple subscript', - 'command expects a filename argument', - '''$1'' expected', - 'invalid section start', - 'grid table is not implemented', - 'general parse error', - 'new section expected', - 'whitespace expected, got ''$1''', - '''$1'' is no valid index file', - 'cannot render reStructuredText element ''$1''', - 'type ''var var'' is not allowed', - '''is'' expects two arguments', - '''is'' expects object types', - '''$1'' can never be of this subtype', - 'interpretation requires too many iterations', - 'cannot interpret node kind ''$1''', - 'field ''$1'' cannot be found', - 'invalid conversion from type ''$1''', - 'assertion failed', - 'cannot generate code for ''$1''', - 'converter needs return type', - 'converter requires one parameter', - 'unhandled exception: $1', - 'macro returned a cyclic abstract syntax tree', - '''$1'' is no macro or template', - '$1', - 'cannot open ''$1'' [CannotOpenFile]', - 'octal escape sequences do not exist; leading zero is ignored [OctalEscape]', - '''$1'' is never read [XIsNeverRead]', - '''$1'' might not have been initialized [XmightNotBeenInit]', - 'cannot write file ''$1'' [CannotWriteMO2]', - 'cannot read file ''$1'' [CannotReadMO2]', - '''$1'' is deprecated [Deprecated]', - '''l'' should not be used as an identifier; may look like ''1'' (one) [SmallLshouldNotBeUsed]', - 'unknown magic ''$1'' might crash the compiler [UnknownMagic]', - 'redefinition of label ''$1'' [RedefinitionOfLabel]', - 'unknown substitution ''$1'' [UnknownSubstitutionX]', - 'language ''$1'' not supported [LanguageXNotSupported]', - 'comment ''$1'' ignored [CommentXIgnored]', - '$1 [User]', - 'operation successful [Success]', - 'operation successful ($1 lines compiled; $2 sec total) [SuccessX]', - 'line too long [LineTooLong]', - '''$1'' is declared but not used [XDeclaredButNotUsed]', - 'conversion to base object is not needed [ConvToBaseNotNeeded]', - 'conversion from $1 to itself is pointless [ConvFromXtoItselfNotNeeded]', - 'expression evaluates always to ''$1'' [ExprAlwaysX]', - 'quit() called [QuitCalled]', - '$1 [Processing]', - 'generated code listing: [CodeBegin]', - 'end of listing [CodeEnd]', - 'used config file ''$1'' [Conf]', - '$1 [User]' - ); -const - WarningsToStr: array [0..13] of string = ( - 'CannotOpenFile', - 'OctalEscape', - 'XIsNeverRead', - 'XmightNotBeenInit', - 'CannotWriteMO2', - 'CannotReadMO2', - 'Deprecated', - 'SmallLshouldNotBeUsed', - 'UnknownMagic', - 'RedefinitionOfLabel', - 'UnknownSubstitutionX', - 'LanguageXNotSupported', - 'CommentXIgnored', - 'User' - ); -const - HintsToStr: array [0..12] of string = ( - 'Success', - 'SuccessX', - 'LineTooLong', - 'XDeclaredButNotUsed', - 'ConvToBaseNotNeeded', - 'ConvFromXtoItselfNotNeeded', - 'ExprAlwaysX', - 'QuitCalled', - 'Processing', - 'CodeBegin', - 'CodeEnd', - 'Conf', - 'User' - ); +type + TMsgKind = ( + errUnknown, + errIllFormedAstX, + errCannotOpenFile, + errInternal, + errGenerated, + errXCompilerDoesNotSupportCpp, + errStringLiteralExpected, + errIntLiteralExpected, + errInvalidCharacterConstant, + errClosingTripleQuoteExpected, + errClosingQuoteExpected, + errTabulatorsAreNotAllowed, + errInvalidToken, + errLineTooLong, + errInvalidNumber, + errNumberOutOfRange, + errNnotAllowedInCharacter, + errClosingBracketExpected, + errMissingFinalQuote, + errIdentifierExpected, + errOperatorExpected, + errTokenExpected, + errStringAfterIncludeExpected, + errRecursiveInclude, + errOnOrOffExpected, + errNoneSpeedOrSizeExpected, + errInvalidPragma, + errUnknownPragma, + errPragmaXHereNotAllowed, + errUnknownDirective, + errInvalidDirective, + errAtPopWithoutPush, + errEmptyAsm, + errAsgnInvalidInExpr, + errInvalidIndentation, + errExceptionExpected, + errExceptionAlreadyHandled, + errReturnNotAllowedHere, + errYieldNotAllowedHere, + errInvalidNumberOfYieldExpr, + errReturnInvalidInIterator, + errCannotReturnExpr, + errAttemptToRedefine, + errStmtInvalidAfterReturn, + errStmtExpected, + errInvalidLabel, + errInvalidCmdLineOption, + errCmdLineArgExpected, + errCmdLineNoArgExpected, + errInvalidVarSubstitution, + errUnknownVar, + errUnknownCcompiler, + errOnOrOffExpectedButXFound, + errNoneBoehmRefcExpectedButXFound, + errNoneSpeedOrSizeExpectedButXFound, + errGuiConsoleOrLibExpectedButXFound, + errUnknownOS, + errUnknownCPU, + errGenOutExpectedButXFound, + errArgsNeedRunOption, + errInvalidMultipleAsgn, + errColonOrEqualsExpected, + errExprExpected, + errUndeclaredIdentifier, + errUseQualifier, + errTwiceForwarded, + errTypeExpected, + errSystemNeeds, + errExecutionOfProgramFailed, + errNotOverloadable, + errInvalidArgForX, + errStmtHasNoEffect, + errXExpectsTypeOrValue, + errXExpectsArrayType, + errIteratorCannotBeInstantiated, + errExprWithNoTypeCannotBeConverted, + errExprWithNoTypeCannotBeCasted, + errConstantDivisionByZero, + errOrdinalTypeExpected, + errOrdinalOrFloatTypeExpected, + errOverOrUnderflow, + errCannotEvalXBecauseIncompletelyDefined, + errChrExpectsRange0_255, + errStaticAssertFailed, + errStaticAssertCannotBeEval, + errDotRequiresRecordOrObjectType, + errUndeclaredFieldX, + errNilAccess, + errIndexOutOfBounds, + errIndexTypesDoNotMatch, + errBracketsInvalidForType, + errValueOutOfSetBounds, + errFieldInitTwice, + errFieldNotInit, + errExprCannotBeCalled, + errExprHasNoType, + errExprXHasNoType, + errCastNotInSafeMode, + errExprCannotBeCastedToX, + errUndefinedPrefixOpr, + errCommaOrParRiExpected, + errCurlyLeOrParLeExpected, + errSectionExpected, + errImplemenationExpected, + errRangeExpected, + errInvalidTypeDescription, + errAttemptToRedefineX, + errMagicOnlyInSystem, + errUnknownOperatorX, + errPowerOfTwoExpected, + errStringMayNotBeEmpty, + errCallConvExpected, + errProcOnlyOneCallConv, + errSymbolMustBeImported, + errExprMustBeBool, + errConstExprExpected, + errDuplicateCaseLabel, + errRangeIsEmpty, + errSelectorMustBeOfCertainTypes, + errSelectorMustBeOrdinal, + errOrdXMustNotBeNegative, + errLenXinvalid, + errWrongNumberOfVariables, + errExprCannotBeRaised, + errBreakOnlyInLoop, + errTypeXhasUnknownSize, + errConstNeedsConstExpr, + errConstNeedsValue, + errResultCannotBeOpenArray, + errSizeTooBig, + errSetTooBig, + errBaseTypeMustBeOrdinal, + errInheritanceOnlyWithNonFinalObjects, + errInheritanceOnlyWithEnums, + errIllegalRecursionInTypeX, + errCannotInstantiateX, + errExprHasNoAddress, + errVarForOutParamNeeded, + errPureTypeMismatch, + errTypeMismatch, + errButExpected, + errButExpectedX, + errAmbigiousCallXYZ, + errWrongNumberOfTypeParams, + errOutParamNoDefaultValue, + errInlineProcHasNoAddress, + errXCannotBeInParamDecl, + errPragmaOnlyInHeaderOfProc, + errImplOfXNotAllowed, + errImplOfXexpected, + errNoSymbolToBorrowFromFound, + errDiscardValue, + errInvalidDiscard, + errUnknownPrecedence, + errIllegalConvFromXtoY, + errTypeMismatchExpectedXGotY, + errCannotBindXTwice, + errInvalidOrderInEnumX, + errEnumXHasWholes, + errExceptExpected, + errInvalidTry, + errEofExpectedButXFound, + errOptionExpected, + errCannotEvaluateForwardConst, + errXisNoLabel, + errXNeedsConcreteType, + errNotAllCasesCovered, + errStringRange, + errUnkownSubstitionVar, + errComplexStmtRequiresInd, + errXisNotCallable, + errNoPragmasAllowedForX, + errNoGenericParamsAllowedForX, + errInvalidParamKindX, + errDefaultArgumentInvalid, + errNamedParamHasToBeIdent, + errNoReturnTypeForX, + errConvNeedsOneArg, + errInvalidPragmaX, + errXNotAllowedHere, + errInvalidControlFlowX, + errATypeHasNoValue, + errXisNoType, + errCircumNeedsPointer, + errInvalidContextForBuiltinX, + errInvalidExpression, + errInvalidExpressionX, + errEnumHasNoValueX, + errNamedExprExpected, + errNamedExprNotAllowed, + errXExpectsOneTypeParam, + errArrayExpectsTwoTypeParams, + errInvalidVisibilityX, + errInitHereNotAllowed, + errXCannotBeAssignedTo, + errIteratorNotAllowed, + errIteratorNeedsImplementation, + errIteratorNeedsReturnType, + errInvalidCommandX, + errXOnlyAtModuleScope, + errTypeXNeedsImplementation, + errTemplateInstantiationTooNested, + errInstantiationFrom, + errInvalidIndexValueForTuple, + errCommandExpectsFilename, + errXExpected, + errInvalidSectionStart, + errGridTableNotImplemented, + errGeneralParseError, + errNewSectionExpected, + errWhitespaceExpected, + errXisNoValidIndexFile, + errCannotRenderX, + errVarVarTypeNotAllowed, + errIsExpectsTwoArguments, + errIsExpectsObjectTypes, + errXcanNeverBeOfThisSubtype, + errTooManyIterations, + errCannotInterpretNodeX, + errFieldXNotFound, + errInvalidConversionFromTypeX, + errAssertionFailed, + errCannotGenerateCodeForX, + errXNeedsReturnType, + errXRequiresOneArgument, + errUnhandledExceptionX, + errCyclicTree, + errXisNoMacroOrTemplate, + errUser, + warnCannotOpenFile, + warnOctalEscape, + warnXIsNeverRead, + warnXmightNotBeenInit, + warnCannotWriteMO2, + warnCannotReadMO2, + warnDeprecated, + warnSmallLshouldNotBeUsed, + warnUnknownMagic, + warnRedefinitionOfLabel, + warnUnknownSubstitutionX, + warnLanguageXNotSupported, + warnCommentXIgnored, + warnUser, + hintSuccess, + hintSuccessX, + hintLineTooLong, + hintXDeclaredButNotUsed, + hintConvToBaseNotNeeded, + hintConvFromXtoItselfNotNeeded, + hintExprAlwaysX, + hintQuitCalled, + hintProcessing, + hintCodeBegin, + hintCodeEnd, + hintConf, + hintUser); + +const + MsgKindToStr: array [TMsgKind] of string = ( + 'unknown error', + 'illformed AST: $1', + 'cannot open ''$1''', + 'internal error: $1', + '$1', + '''$1'' compiler does not support C++', + 'string literal expected', + 'integer literal expected', + 'invalid character constant', + 'closing """ expected, but end of file reached', + 'closing " expected', + 'tabulators are not allowed', + 'invalid token: $1', + 'line too long', + '$1 is not a valid number', + 'number $1 out of valid range', + '\n not allowed in character literal', + 'closing '']'' expected, but end of file reached', + 'missing final ''', + 'identifier expected, but found ''$1''', + 'operator expected, but found ''$1''', + '''$1'' expected', + 'string after ''include'' expected', + 'recursive include file: ''$1''', + '''on'' or ''off'' expected', + '''none'', ''speed'' or ''size'' expected', + 'invalid pragma', + 'unknown pragma: ''$1''', + 'pragma ''$1'' here not allowed', + 'unknown directive: ''$1''', + 'invalid directive', + '''pop'' without a ''push'' pragma', + 'empty asm statement makes no sense', + '''='' invalid in an expression; probably ''=='' meant', + 'invalid indentation', + 'exception expected', + 'exception already handled', + '''return'' only allowed in routine', + '''yield'' only allowed in a loop of an iterator', + 'invalid number of ''yield'' expresions', + '''return'' not allowed in iterator', + 'current routine cannot return an expression', + 'attempt to redefine ''$1''', + 'statement not allowed after ''return'', ''break'' or ''raise''', + 'statement expected', + '''$1'' is no label', + 'invalid command line option: ''$1''', + 'argument for command line option expected: ''$1''', + 'invalid argument for command line option: ''$1''', + 'invalid variable substitution in ''$1''', + 'unknown variable: ''$1''', + 'unknown C compiler: ''$1''', + '''on'' or ''off'' expected, but ''$1'' found', + '''none'', ''boehm'' or ''refc'' expected, but ''$1'' found', + '''none'', ''speed'' or ''size'' expected, but ''$1'' found', + '''gui'', ''console'' or ''lib'' expected, but ''$1'' found', + 'unknown OS: ''$1''', + 'unknown CPU: ''$1''', + '''c'', ''c++'' or ''yaml'' expected, but ''$1'' found', + 'arguments can only be given if the ''--run'' option is selected', + 'multiple assignment is not allowed', + ''':'' or ''='' expected, but found ''$1''', + 'expression expected, but found ''$1''', + 'undeclared identifier: ''$1''', + 'ambigious identifier: ''$1'' -- use a qualifier', + '''$1'' is forwarded twice', + 'type expected', + 'system module needs ''$1''', + 'execution of an external program failed', + 'overloaded ''$1'' leads to ambigious calls', + 'invalid argument for ''$1''', + 'statement has no effect', + '''$1'' expects a type or value', + '''$1'' expects an array type', + '''$1'' cannot be instantiated because its body has not been compiled yet', + 'expression with no type cannot be converted', + 'expression with no type cannot be casted', + 'constant division by zero', + 'ordinal type expected', + 'ordinal or float type expected', + 'over- or underflow', + 'cannot evalutate ''$1'' because type is not defined completely', + '''chr'' expects an int in the range 0..255', + '''staticAssert'' failed: condition is false', + 'argument to ''staticAssert'' cannot be evaluated at compile time', + '''.'' requires a record or object type', + 'undeclared field: ''$1''', + 'attempt to access a nil address', + 'index out of bounds', + 'index types do not match', + '''[]'' operator invalid for this type', + 'value out of set bounds', + 'field initialized twice: ''$1''', + 'field ''$1'' not initialized', + 'expression cannot be called', + 'expression has no type', + 'expression ''$1'' has no type', + '''cast'' not allowed in safe mode', + 'expression cannot be casted to $1', + 'undefined prefix operator: $1', + ''','' or '')'' expected', + '''{'' or ''('' expected', + 'section (''type'', ''proc'', etc.) expected', + '''implementation'' or end of file expected', + 'range expected', + 'invalid type description', + 'attempt to redefine ''$1''', + '''magic'' only allowed in system module', + 'unkown operator: ''$1''', + 'power of two expected', + 'string literal may not be empty', + 'calling convention expected', + 'a proc can only have one calling convention', + 'symbol must be imported if ''lib'' pragma is used', + 'expression must be of type ''bool''', + 'constant expression expected', + 'duplicate case label', + 'range is empty', + 'selector must be of an ordinal type, real or string', + 'selector must be of an ordinal type', + 'ord($1) must not be negative', + 'len($1) must be less than 32768', + 'wrong number of variables', + 'only objects can be raised', + '''break'' only allowed in loop construct', + 'type ''$1'' has unknown size', + 'a constant can only be initialized with a constant expression', + 'a constant needs a value', + 'the result type cannot be on open array', + 'computing the type''s size produced an overflow', + 'set is too large', + 'base type of a set must be an ordinal', + 'inheritance only works with non-final objects', + 'inheritance only works with an enum', + 'illegal recursion in type ''$1''', + 'cannot instantiate: ''$1''', + 'expression has no address', + 'for a ''var'' type a variable needs to be passed', + 'type mismatch', + 'type mismatch: got (', + 'but expected one of: ', + 'but expected ''$1''', + 'ambigious call; both $1 and $2 match for: $3', + 'wrong number of type parameters', + 'out parameters cannot have default values', + 'an inline proc has no address', + '$1 cannot be declared in parameter declaration', + 'pragmas are only in the header of a proc allowed', + 'implementation of ''$1'' is not allowed', + 'implementation of ''$1'' expected', + 'no symbol to borrow from found', + 'value returned by statement has to be discarded', + 'statement returns no value that can be discarded', + 'unknown precedence for operator; use ''infix: prec'' pragma', + 'conversion from $1 to $2 is invalid', + 'type mismatch: expected ''$1'', but got ''$2''', + 'cannot bind parameter ''$1'' twice', + 'invalid order in enum ''$1''', + 'enum ''$1'' has wholes', + '''except'' or ''finally'' expected', + 'after catch all ''except'' or ''finally'' no section may follow', + 'end of file expected, but found token ''$1''', + 'option expected, but found ''$1''', + 'cannot evaluate forwarded constant', + '''$1'' is not a label', + '''$1'' needs to be of a non-generic type', + 'not all cases are covered', + 'string range in case statement not allowed', + 'unknown substitution variable: ''$1''', + 'complex statement requires indentation', + '''$1'' is not callable', + 'no pragmas allowed for $1', + 'no generic parameters allowed for $1', + 'invalid param kind: ''$1''', + 'default argument invalid', + 'named parameter has to be an identifier', + 'no return type for $1 allowed', + 'a type conversion needs exactly one argument', + 'invalid pragma: $1', + '$1 here not allowed', + 'invalid control flow: $1', + 'a type has no value', + 'invalid type: ''$1''', + '''^'' needs a pointer or reference type', + 'invalid context for builtin ''$1''', + 'invalid expression', + 'invalid expression: ''$1''', + 'enum has no value ''$1''', + 'named expression expected', + 'named expression here not allowed', + '''$1'' expects one type parameter', + 'array expects two type parameters', + 'invalid invisibility: ''$1''', + 'initialization here not allowed', + '''$1'' cannot be assigned to', + 'iterators can only be defined at the module''s top level', + 'iterator needs an implementation', + 'iterator needs a return type', + 'invalid command: ''$1''', + '''$1'' is only allowed at top level', + 'type ''$1'' needs an implementation', + 'template instantiation too nested', + 'instantiation from here', + 'invalid index value for tuple subscript', + 'command expects a filename argument', + '''$1'' expected', + 'invalid section start', + 'grid table is not implemented', + 'general parse error', + 'new section expected', + 'whitespace expected, got ''$1''', + '''$1'' is no valid index file', + 'cannot render reStructuredText element ''$1''', + 'type ''var var'' is not allowed', + '''is'' expects two arguments', + '''is'' expects object types', + '''$1'' can never be of this subtype', + 'interpretation requires too many iterations', + 'cannot interpret node kind ''$1''', + 'field ''$1'' cannot be found', + 'invalid conversion from type ''$1''', + 'assertion failed', + 'cannot generate code for ''$1''', + 'converter needs return type', + 'converter requires one parameter', + 'unhandled exception: $1', + 'macro returned a cyclic abstract syntax tree', + '''$1'' is no macro or template', + '$1', + 'cannot open ''$1'' [CannotOpenFile]', + 'octal escape sequences do not exist; leading zero is ignored [OctalEscape]', + '''$1'' is never read [XIsNeverRead]', + '''$1'' might not have been initialized [XmightNotBeenInit]', + 'cannot write file ''$1'' [CannotWriteMO2]', + 'cannot read file ''$1'' [CannotReadMO2]', + '''$1'' is deprecated [Deprecated]', + '''l'' should not be used as an identifier; may look like ''1'' (one) [SmallLshouldNotBeUsed]', + 'unknown magic ''$1'' might crash the compiler [UnknownMagic]', + 'redefinition of label ''$1'' [RedefinitionOfLabel]', + 'unknown substitution ''$1'' [UnknownSubstitutionX]', + 'language ''$1'' not supported [LanguageXNotSupported]', + 'comment ''$1'' ignored [CommentXIgnored]', + '$1 [User]', + 'operation successful [Success]', + 'operation successful ($1 lines compiled; $2 sec total) [SuccessX]', + 'line too long [LineTooLong]', + '''$1'' is declared but not used [XDeclaredButNotUsed]', + 'conversion to base object is not needed [ConvToBaseNotNeeded]', + 'conversion from $1 to itself is pointless [ConvFromXtoItselfNotNeeded]', + 'expression evaluates always to ''$1'' [ExprAlwaysX]', + 'quit() called [QuitCalled]', + '$1 [Processing]', + 'generated code listing: [CodeBegin]', + 'end of listing [CodeEnd]', + 'used config file ''$1'' [Conf]', + '$1 [User]' + ); +const + WarningsToStr: array [0..13] of string = ( + 'CannotOpenFile', + 'OctalEscape', + 'XIsNeverRead', + 'XmightNotBeenInit', + 'CannotWriteMO2', + 'CannotReadMO2', + 'Deprecated', + 'SmallLshouldNotBeUsed', + 'UnknownMagic', + 'RedefinitionOfLabel', + 'UnknownSubstitutionX', + 'LanguageXNotSupported', + 'CommentXIgnored', + 'User' + ); +const + HintsToStr: array [0..12] of string = ( + 'Success', + 'SuccessX', + 'LineTooLong', + 'XDeclaredButNotUsed', + 'ConvToBaseNotNeeded', + 'ConvFromXtoItselfNotNeeded', + 'ExprAlwaysX', + 'QuitCalled', + 'Processing', + 'CodeBegin', + 'CodeEnd', + 'Conf', + 'User' + ); //[[[end]]] const diff --git a/nim/nimconf.pas b/nim/nimconf.pas index 8f908bf62..842446ae9 100644 --- a/nim/nimconf.pas +++ b/nim/nimconf.pas @@ -335,12 +335,19 @@ end; procedure LoadConfig(const project: string); var - conffile: string; + conffile, prefix: string; begin // set default value (can be overwritten): - if libpath = '' then + if libpath = '' then begin // choose default libpath: - libpath := joinPath(getPrefixDir(), 'lib'); + prefix := getPrefixDir(); + if (prefix = '/usr') then + libpath := '/usr/lib/nimrod' + else if (prefix = '/usr/local') then + libpath := '/usr/local/lib/nimrod' + else + libpath := joinPath(prefix, 'lib') + end; // read default config file: LoadSpecialConfig('nimrod.cfg'); // read project config file: diff --git a/nim/nversion.pas b/nim/nversion.pas index ae6392db9..e15f88068 100644 --- a/nim/nversion.pas +++ b/nim/nversion.pas @@ -31,10 +31,10 @@ const //cog.outl('VersionMinor = %s;' % ver[1]) //cog.outl('VersionPatch = %s;' % ver[2]) //]]] - VersionAsString = '0.7.8'; + VersionAsString = '0.7.10'; VersionMajor = 0; VersionMinor = 7; - VersionPatch = 8; + VersionPatch = 10; //[[[[end]]]] implementation diff --git a/nim/parsecfg.pas b/nim/parsecfg.pas index 620335aa6..ba6a98679 100644 --- a/nim/parsecfg.pas +++ b/nim/parsecfg.pas @@ -1,7 +1,7 @@ // // // Nimrod's Runtime Library -// (c) Copyright 2008 Andreas Rumpf +// (c) Copyright 2009 Andreas Rumpf // // See the file "copying.txt", included in this // distribution, for details about the copyright. @@ -201,6 +201,7 @@ begin inc(pos, 2); // skip "" // skip leading newline: pos := HandleCRLF(c, pos); + buf := c.buf; repeat case buf[pos] of '"': begin @@ -211,6 +212,7 @@ begin end; CR, LF: begin pos := HandleCRLF(c, pos); + buf := c.buf; tok.literal := tok.literal +{&} nl; end; lexbase.EndOfFile: begin @@ -278,7 +280,10 @@ begin ' ': Inc(pos); Tabulator: inc(pos); '#', ';': while not (buf[pos] in [CR, LF, lexbase.EndOfFile]) do inc(pos); - CR, LF: pos := HandleCRLF(c, pos); + CR, LF: begin + pos := HandleCRLF(c, pos); + buf := c.buf; + end else break // EndOfFile also leaves the loop end until false; diff --git a/nim/paslex.pas b/nim/paslex.pas index da9283163..f3d8daaeb 100644 --- a/nim/paslex.pas +++ b/nim/paslex.pas @@ -1,7 +1,7 @@ // // // The Nimrod Compiler -// (c) Copyright 2008 Andreas Rumpf +// (c) Copyright 2009 Andreas Rumpf // // See the file "copying.txt", included in this // distribution, for details about the copyright. @@ -529,6 +529,7 @@ begin addChar(tok.literal, buf[pos]); inc(pos); end; pos := handleCRLF(L, pos); + buf := L.buf; indent := 0; while buf[pos] = ' ' do begin inc(pos); inc(indent) end; if (col = indent) and (buf[pos] = '/') and (buf[pos+1] = '/') then @@ -552,6 +553,7 @@ begin case buf[pos] of CR, LF: begin pos := HandleCRLF(L, pos); + buf := L.buf; tok.literal := tok.literal +{&} nl + '#'; end; '}': begin inc(pos); break end; @@ -578,6 +580,7 @@ begin case buf[pos] of CR, LF: begin pos := HandleCRLF(L, pos); + buf := L.buf; tok.literal := tok.literal +{&} nl + '#'; end; '*': begin @@ -606,7 +609,10 @@ begin case buf[pos] of ' ', Tabulator: Inc(pos); // newline is special: - CR, LF: pos := HandleCRLF(L, pos); + CR, LF: begin + pos := HandleCRLF(L, pos); + buf := L.buf; + end else break // EndOfFile also leaves the loop end until false; diff --git a/nim/pnimsyn.pas b/nim/pnimsyn.pas index 95d6e64f9..51c0cd4f5 100644 --- a/nim/pnimsyn.pas +++ b/nim/pnimsyn.pas @@ -1,7 +1,7 @@ // // // The Nimrod Compiler -// (c) Copyright 2008 Andreas Rumpf +// (c) Copyright 2009 Andreas Rumpf // // See the file "copying.txt", included in this // distribution, for details about the copyright. @@ -1663,6 +1663,14 @@ begin addSon(result, parseRecordPart(p)); end; +function parseAbstract(var p: TParser): PNode; +begin + result := newNodeP(nkAbstractTy, p); + getTok(p); + optInd(p, result); + addSon(result, parseTypeDesc(p)); +end; + function parseTypeDef(var p: TParser): PNode; var a: PNode; @@ -1676,6 +1684,7 @@ begin case p.tok.tokType of tkObject: a := parseRecordOrObject(p, nkObjectTy); tkEnum: a := parseEnum(p); + tkAbstract: a := parseAbstract(p); else a := parseTypeDesc(p); end; addSon(result, a); diff --git a/nim/pragmas.pas b/nim/pragmas.pas index df48f27c9..9f4a543c5 100644 --- a/nim/pragmas.pas +++ b/nim/pragmas.pas @@ -522,6 +522,10 @@ begin if sym.typ = nil then invalidPragma(it); include(sym.typ.flags, tfVarargs); end; + wBorrow: begin + noVal(it); + include(sym.flags, sfBorrow); + end; wFinal: begin noVal(it); if sym.typ = nil then invalidPragma(it); @@ -595,7 +599,8 @@ begin pragma(c, s, n, {@set}[FirstCallConv..LastCallConv, wImportc, wExportc, wNodecl, wMagic, wNosideEffect, wNoreturn, wDynLib, wHeader, wCompilerProc, wPure, - wCppMethod, wDeprecated, wVarargs, wCompileTime, wMerge]); + wCppMethod, wDeprecated, wVarargs, wCompileTime, wMerge, + wBorrow]); end; procedure pragmaMacro(c: PContext; s: PSym; n: PNode); @@ -608,7 +613,7 @@ end; procedure pragmaIterator(c: PContext; s: PSym; n: PNode); begin pragma(c, s, n, {@set}[FirstCallConv..LastCallConv, - wImportc, wExportc, wNodecl, wMagic, wDeprecated]); + wImportc, wExportc, wNodecl, wMagic, wDeprecated, wBorrow]); end; procedure pragmaStmt(c: PContext; s: PSym; n: PNode); diff --git a/nim/procfind.pas b/nim/procfind.pas index 9c4786e53..c8792586a 100644 --- a/nim/procfind.pas +++ b/nim/procfind.pas @@ -1,7 +1,7 @@ // // // The Nimrod Compiler -// (c) Copyright 2008 Andreas Rumpf +// (c) Copyright 2009 Andreas Rumpf // // See the file "copying.txt", included in this // distribution, for details about the copyright. @@ -22,6 +22,10 @@ function SearchForProc(c: PContext; fn: PSym; tos: int): PSym; // Searchs for the fn in the symbol table. If the parameter lists are exactly // the same the sym in the symbol table is returned, else nil. +function SearchForBorrowProc(c: PContext; fn: PSym; tos: int): PSym; +// Searchs for the fn in the symbol table. If the parameter lists are suitable +// for borrowing the sym in the symbol table is returned, else nil. + implementation function equalGenericParams(procA, procB: PNode): Boolean; @@ -69,4 +73,46 @@ begin end end; +function paramsFitBorrow(a, b: PNode): bool; +var + i, len: int; + m, n: PSym; +begin + len := sonsLen(a); + result := false; + if len = sonsLen(b) then begin + for i := 1 to len-1 do begin + m := a.sons[i].sym; + n := b.sons[i].sym; + assert((m.kind = skParam) and (n.kind = skParam)); + if not equalOrAbstractOf(m.typ, n.typ) then exit; + end; + // return type: + if not equalOrAbstractOf(a.sons[0].typ, b.sons[0].typ) then exit; + result := true + end +end; + +function SearchForBorrowProc(c: PContext; fn: PSym; tos: int): PSym; +// Searchs for the fn in the symbol table. If the parameter lists are suitable +// for borrowing the sym in the symbol table is returned, else nil. +var + it: TIdentIter; + scope: int; +begin + for scope := tos downto 0 do begin + result := initIdentIter(it, c.tab.stack[scope], fn.Name); + while result <> nil do begin + // watchout! result must not be the same as fn! + if (result.Kind = fn.kind) and (result.id <> fn.id) then begin + if equalGenericParams(result.ast.sons[genericParamsPos], + fn.ast.sons[genericParamsPos]) then begin + if paramsFitBorrow(fn.typ.n, result.typ.n) then exit; + end + end; + result := NextIdentIter(it, c.tab.stack[scope]) + end + end +end; + end. diff --git a/nim/rnimsyn.pas b/nim/rnimsyn.pas index 6cb78efcf..5be10a0f3 100644 --- a/nim/rnimsyn.pas +++ b/nim/rnimsyn.pas @@ -16,7 +16,7 @@ unit rnimsyn; interface uses - nsystem, charsets, lexbase, scanner, options, idents, strutils, ast, msgs, + nsystem, charsets, scanner, options, idents, strutils, ast, msgs, lists; type @@ -543,6 +543,7 @@ begin nkRefTy: result := lsub(n.sons[0])+length('ref_'); nkPtrTy: result := lsub(n.sons[0])+length('ptr_'); nkVarTy: result := lsub(n.sons[0])+length('var_'); + nkAbstractTy: result := lsub(n.sons[0])+length('abstract_'); nkTypeDef: result := lsons(n)+3; nkOfInherit: result := lsub(n.sons[0])+length('of_'); nkProcTy: result := lsons(n)+length('proc_'); @@ -1159,6 +1160,10 @@ begin putWithSpace(g, tkVar, 'var'); gsub(g, n.sons[0]); end; + nkAbstractTy: begin + putWithSpace(g, tkAbstract, 'abstract'); + gsub(g, n.sons[0]); + end; nkTypeDef: begin gsub(g, n.sons[0]); gsub(g, n.sons[1]); diff --git a/nim/rst.pas b/nim/rst.pas index 6d0d476c9..d2afc7e33 100644 --- a/nim/rst.pas +++ b/nim/rst.pas @@ -1991,7 +1991,7 @@ begin addSon(n, newRstNode(rnLeaf, readFile(path))); result.sons[2] := n; end; - result.kind := rnCodeBlock + result.kind := rnCodeBlock; end; function dirContainer(var p: TRstParser): PRstNode; diff --git a/nim/scanner.pas b/nim/scanner.pas index 51532c801..d1f32135c 100644 --- a/nim/scanner.pas +++ b/nim/scanner.pas @@ -52,20 +52,20 @@ type // i = i + 1 //cog.out(idents) //]]] - tkAddr, tkAnd, tkAs, tkAsm, - tkBlock, tkBreak, tkCase, tkCast, - tkConst, tkContinue, tkConverter, tkDiscard, - tkDiv, tkElif, tkElse, tkEnd, - tkEnum, tkExcept, tkException, tkFinally, - tkFor, tkFrom, tkGeneric, tkIf, - tkImplies, tkImport, tkIn, tkInclude, - tkIs, tkIsnot, tkIterator, tkLambda, - tkMacro, tkMethod, tkMod, tkNil, - tkNot, tkNotin, tkObject, tkOf, - tkOr, tkOut, tkProc, tkPtr, - tkRaise, tkRef, tkReturn, tkShl, - tkShr, tkTemplate, tkTry, tkTuple, - tkType, tkVar, tkWhen, tkWhere, + tkAbstract, tkAddr, tkAnd, tkAs, + tkAsm, tkBlock, tkBreak, tkCase, + tkCast, tkConst, tkContinue, tkConverter, + tkDiscard, tkDiv, tkElif, tkElse, + tkEnd, tkEnum, tkExcept, tkException, + tkFinally, tkFor, tkFrom, tkGeneric, + tkIf, tkImplies, tkImport, tkIn, + tkInclude, tkIs, tkIsnot, tkIterator, + tkLambda, tkMacro, tkMethod, tkMod, + tkNil, tkNot, tkNotin, tkObject, + tkOf, tkOr, tkOut, tkProc, + tkPtr, tkRaise, tkRef, tkReturn, + tkShl, tkShr, tkTemplate, tkTry, + tkTuple, tkType, tkVar, tkWhen, tkWhile, tkWith, tkWithout, tkXor, tkYield, //[[[end]]] @@ -96,20 +96,20 @@ const //[[[cog //cog.out(strings) //]]] - 'addr', 'and', 'as', 'asm', - 'block', 'break', 'case', 'cast', - 'const', 'continue', 'converter', 'discard', - 'div', 'elif', 'else', 'end', - 'enum', 'except', 'exception', 'finally', - 'for', 'from', 'generic', 'if', - 'implies', 'import', 'in', 'include', - 'is', 'isnot', 'iterator', 'lambda', - 'macro', 'method', 'mod', 'nil', - 'not', 'notin', 'object', 'of', - 'or', 'out', 'proc', 'ptr', - 'raise', 'ref', 'return', 'shl', - 'shr', 'template', 'try', 'tuple', - 'type', 'var', 'when', 'where', + 'abstract', 'addr', 'and', 'as', + 'asm', 'block', 'break', 'case', + 'cast', 'const', 'continue', 'converter', + 'discard', 'div', 'elif', 'else', + 'end', 'enum', 'except', 'exception', + 'finally', 'for', 'from', 'generic', + 'if', 'implies', 'import', 'in', + 'include', 'is', 'isnot', 'iterator', + 'lambda', 'macro', 'method', 'mod', + 'nil', 'not', 'notin', 'object', + 'of', 'or', 'out', 'proc', + 'ptr', 'raise', 'ref', 'return', + 'shl', 'shr', 'template', 'try', + 'tuple', 'type', 'var', 'when', 'while', 'with', 'without', 'xor', 'yield', //[[[end]]] @@ -648,6 +648,7 @@ begin inc(pos, 2); // skip "" // skip leading newline: pos := HandleCRLF(L, pos); + buf := L.buf; repeat case buf[pos] of '"': begin @@ -658,6 +659,7 @@ begin end; CR, LF: begin pos := HandleCRLF(L, pos); + buf := L.buf; tok.literal := tok.literal +{&} tnl; end; lexbase.EndOfFile: begin @@ -842,6 +844,7 @@ begin addChar(tok.literal, buf[pos]); inc(pos); end; pos := handleCRLF(L, pos); + buf := L.buf; indent := 0; while buf[pos] = ' ' do begin inc(pos); inc(indent) end; if (buf[pos] = '#') and (col = indent) then begin @@ -875,6 +878,7 @@ begin // newline is special: CR, LF: begin pos := HandleCRLF(L, pos); + buf := L.buf; indent := 0; while buf[pos] = ' ' do begin Inc(pos); Inc(indent) diff --git a/nim/sem.pas b/nim/sem.pas index 09f9bf49b..c0826bdbe 100644 --- a/nim/sem.pas +++ b/nim/sem.pas @@ -134,6 +134,7 @@ var p: PEvalContext; s: PStackFrame; begin + include(sym.flags, sfUsed); p := newEvalContext(c.module, ''); s := newStackFrame(); s.call := n; @@ -156,7 +157,8 @@ end; procedure CheckBool(t: PNode); begin - if (t.Typ = nil) or (skipVarGeneric(t.Typ).kind <> tyBool) then + if (t.Typ = nil) or (skipTypes(t.Typ, {@set}[tyGenericInst, + tyVar, tyOrdinal]).kind <> tyBool) then liMessage(t.Info, errExprMustBeBool); end; diff --git a/nim/semexprs.pas b/nim/semexprs.pas index 59d7f969a..74cd44b3d 100644 --- a/nim/semexprs.pas +++ b/nim/semexprs.pas @@ -58,8 +58,8 @@ begin end; // common case first (converting of objects) - d := skipVarGeneric(castDest); - s := skipVarGeneric(src); + d := skipTypes(castDest, abstractVar); + s := skipTypes(src, abstractVar); while (d <> nil) and (d.Kind in [tyPtr, tyRef]) and (d.Kind = s.Kind) do begin d := base(d); @@ -71,17 +71,20 @@ begin [typeToString(src), typeToString(castDest)])); if (d.Kind = tyObject) and (s.Kind = tyObject) then checkConversionBetweenObjects(info, d, s) - else if (skipVarGenericRange(castDest).Kind in IntegralTypes) - and (skipVarGenericRange(src).Kind in IntegralTypes) then begin + else if (skipTypes(castDest, abstractVarRange).Kind in IntegralTypes) + and (skipTypes(src, abstractVarRange).Kind in IntegralTypes) then begin // accept conversion between intregral types end - else begin + else begin + // we use d, s here to speed up that operation a bit: case cmpTypes(d, s) of - isNone, isGeneric: - // we use d, s here to speed up that operation a bit - liMessage(info, errGenerated, - format(MsgKindToString(errIllegalConvFromXtoY), - [typeToString(src), typeToString(castDest)])); + isNone, isGeneric: begin + if not equalOrAbstractOf(castDest, src) and + not equalOrAbstractOf(src, castDest) then + liMessage(info, errGenerated, + format(MsgKindToString(errIllegalConvFromXtoY), + [typeToString(src), typeToString(castDest)])); + end else begin end end end @@ -102,8 +105,8 @@ begin else if ss < 0 then result := false else result := (ds >= ss) or - (skipGeneric(dst).kind in [tyInt..tyFloat128]) or - (skipGeneric(src).kind in [tyInt..tyFloat128]) + (skipTypes(dst, abstractInst).kind in [tyInt..tyFloat128]) or + (skipTypes(src, abstractInst).kind in [tyInt..tyFloat128]) end; function semConv(c: PContext; n: PNode; s: PSym): PNode; @@ -138,7 +141,7 @@ begin liMessage(n.info, errXExpectsTypeOrValue, opToStr[m]) else begin n.sons[1] := semExprWithType(c, n.sons[1], {@set}[efAllowType]); - typ := skipVarGenericRange(n.sons[1].typ); + typ := skipTypes(n.sons[1].typ, abstractVarRange); case typ.Kind of tySequence, tyString, tyOpenArray: begin n.typ := getSysType(tyInt); @@ -279,7 +282,8 @@ begin addSon(result.typ, newTypeS(tyEmpty, c)) // needs an empty basetype! else begin addSon(result, semExprWithType(c, n.sons[0])); - typ := skipVar(result.sons[0].typ); + typ := skipTypes(result.sons[0].typ, + {@set}[tyGenericInst, tyVar, tyOrdinal]); for i := 1 to sonsLen(n)-1 do begin n.sons[i] := semExprWithType(c, n.sons[i]); addSon(result, fitNode(c, typ, n.sons[i])); @@ -306,17 +310,18 @@ begin nkHiddenStdConv, nkHiddenSubConv: begin if it.sons[1].kind = nkBracket then it.sons[1] := semArrayConstr(c, it.sons[1]); - if skipVarGeneric(it.typ).kind = tyOpenArray then begin - s := skipVarGeneric(it.sons[1].typ); + if skipTypes(it.typ, abstractVar).kind = tyOpenArray then begin + s := skipTypes(it.sons[1].typ, abstractVar); if (s.kind = tyArrayConstr) and (s.sons[1].kind = tyEmpty) then begin s := copyType(s, getCurrOwner(), false); - skipVarGeneric(s).sons[1] := elemType(skipVarGeneric(it.typ)); + skipTypes(s, abstractVar).sons[1] := elemType( + skipTypes(it.typ, abstractVar)); it.sons[1].typ := s; end end - else if skipVarGeneric(it.sons[1].typ).kind in [tyNil, tyArrayConstr, - tyTuple, tySet] then begin - s := skipVarGeneric(it.typ); + else if skipTypes(it.sons[1].typ, abstractVar).kind in + [tyNil, tyArrayConstr, tyTuple, tySet] then begin + s := skipTypes(it.typ, abstractVar); changeType(it.sons[1], s); n.sons[i] := it.sons[1]; end @@ -335,7 +340,7 @@ function skipObjConv(n: PNode): PNode; begin case n.kind of nkHiddenStdConv, nkHiddenSubConv, nkConv: begin - if skipPtrsGeneric(n.sons[1].typ).kind in [tyTuple, tyObject] then + if skipTypes(n.sons[1].typ, abstractPtrs).kind in [tyTuple, tyObject] then result := n.sons[1] else result := n @@ -352,7 +357,7 @@ begin nkSym: result := n.sym.kind in [skVar, skTemp]; nkDotExpr, nkQualified, nkBracketExpr: begin checkMinSonsLen(n, 1); - if skipGeneric(n.sons[0].typ).kind in [tyVar, tyPtr, tyRef] then + if skipTypes(n.sons[0].typ, abstractInst).kind in [tyVar, tyPtr, tyRef] then result := true else result := isAssignable(n.sons[0]); @@ -361,7 +366,7 @@ begin // Object and tuple conversions are still addressable, so we skip them //if skipPtrsGeneric(n.sons[1].typ).kind in [tyOpenArray, // tyTuple, tyObject] then - if skipPtrsGeneric(n.typ).kind in [tyOpenArray, tyTuple, tyObject] then + if skipTypes(n.typ, abstractPtrs).kind in [tyOpenArray, tyTuple, tyObject] then result := isAssignable(n.sons[1]) end; nkHiddenDeref, nkDerefExpr: result := true; @@ -391,7 +396,7 @@ begin result := n; case n.kind of nkSym: begin - if skipGeneric(n.sym.typ).kind <> tyVar then begin + if skipTypes(n.sym.typ, abstractInst).kind <> tyVar then begin include(n.sym.flags, sfAddrTaken); result := newHiddenAddrTaken(c, n); end @@ -400,14 +405,14 @@ begin checkSonsLen(n, 2); if n.sons[1].kind <> nkSym then internalError(n.info, 'analyseIfAddressTaken'); - if skipGeneric(n.sons[1].sym.typ).kind <> tyVar then begin + if skipTypes(n.sons[1].sym.typ, abstractInst).kind <> tyVar then begin include(n.sons[1].sym.flags, sfAddrTaken); result := newHiddenAddrTaken(c, n); end end; nkBracketExpr: begin checkMinSonsLen(n, 1); - if skipGeneric(n.sons[0].typ).kind <> tyVar then begin + if skipTypes(n.sons[0].typ, abstractInst).kind <> tyVar then begin if n.sons[0].kind = nkSym then include(n.sons[0].sym.flags, sfAddrTaken); result := newHiddenAddrTaken(c, n); @@ -433,7 +438,7 @@ begin if (n.sons[0].kind = nkSym) and (n.sons[0].sym.magic in FakeVarParams) then exit; for i := 1 to sonsLen(n)-1 do - if (i < sonsLen(t)) and (skipGeneric(t.sons[i]).kind = tyVar) then + if (i < sonsLen(t)) and (skipTypes(t.sons[i], abstractInst).kind = tyVar) then n.sons[i] := analyseIfAddressTaken(c, n.sons[i]); end; @@ -503,16 +508,16 @@ begin fixAbstractType(c, result); analyseIfAddressTakenInCall(c, result); end; - +(* function semIncSucc(c: PContext; n: PNode; const opr: string): PNode; // handles Inc, Dec, Succ and Pred var a: PNode; typ: PType; begin - checkMinSonsLen(n, 1); + checkMinSonsLen(n, 2); n.sons[1] := semExprWithType(c, n.sons[1]); - typ := skipVar(n.sons[1].Typ); + typ := skipTypes(n.sons[1].Typ, {@set}[tyGenericInst, tyVar]); if not isOrdinalType(typ) or enumHasWholes(typ) then liMessage(n.sons[1].Info, errOrdinalTypeExpected); if sonsLen(n) = 3 then begin @@ -537,10 +542,27 @@ function semOrd(c: PContext; n: PNode): PNode; begin checkSonsLen(n, 2); n.sons[1] := semExprWithType(c, n.sons[1]); - if not isOrdinalType(skipVar(n.sons[1].Typ)) then + if not isOrdinalType(skipTypes(n.sons[1].Typ, {@set}[tyGenericInst, tyVar])) then liMessage(n.Info, errOrdinalTypeExpected); n.typ := getSysType(tyInt); result := n +end; *) + +function semEcho(c: PContext; n: PNode): PNode; +var + i: int; + call, arg: PNode; +begin + // this really is a macro + checkMinSonsLen(n, 1); + for i := 1 to sonsLen(n)-1 do begin + arg := semExprWithType(c, n.sons[i]); + call := newNodeI(nkCall, arg.info); + addSon(call, newIdentNode(getIdent('$'+''), n.info)); + addSon(call, arg); + n.sons[i] := semExpr(c, call); + end; + result := n; end; function LookUpForDefined(c: PContext; n: PNode): PSym; @@ -609,6 +631,8 @@ begin mHigh: result := semLowHigh(c, setMs(n, s), mHigh); mSizeOf: result := semSizeof(c, setMs(n, s)); mIs: result := semIs(c, setMs(n, s)); + mEcho: result := semEcho(c, setMs(n, s)); + (* mSucc: begin result := semIncSucc(c, setMs(n, s), 'succ'); result.typ := n.sons[1].typ; @@ -619,7 +643,7 @@ begin end; mInc: result := semIncSucc(c, setMs(n, s), 'inc'); ast.mDec: result := semIncSucc(c, setMs(n, s), 'dec'); - mOrd: result := semOrd(c, setMs(n, s)); + mOrd: result := semOrd(c, setMs(n, s)); *) else result := semDirectOp(c, n); end; end; @@ -659,7 +683,14 @@ begin result.info := n.info; result.typ := s.typ; end - end + end; + skMacro: result := semMacroExpr(c, n, s); + skTemplate: begin + // Templates and macros can be invoked without ``()`` + pushInfoContext(n.info); + result := evalTemplate(c, n, s); + popInfoContext(); + end; else begin end end; checkDeprecated(n, s); @@ -808,7 +839,7 @@ begin exit end; - ty := skipPtrsGeneric(ty); + ty := skipTypes(ty, {@set}[tyGenericInst, tyVar, tyPtr, tyRef]); if ty.kind = tyObject then begin while true do begin check := nil; @@ -816,7 +847,7 @@ begin //f := lookupInRecord(ty.n, i); if f <> nil then break; if ty.sons[0] = nil then break; - ty := skipGeneric(ty.sons[0]); + ty := skipTypes(ty.sons[0], {@set}[tyGenericInst]); end; if f <> nil then begin if ([sfStar, sfMinus] * f.flags <> []) @@ -883,7 +914,7 @@ begin // check if array type: checkMinSonsLen(n, 2); n.sons[0] := semExprWithType(c, n.sons[0], flags-[efAllowType]); - arr := skipPtrsGeneric(n.sons[0].typ); + arr := skipTypes(n.sons[0].typ, {@set}[tyGenericInst, tyVar, tyPtr, tyRef]); case arr.kind of tyArray, tyOpenArray, tyArrayConstr, tySequence, tyString, tyCString: begin @@ -904,7 +935,8 @@ begin n.sons[0] := makeDeref(n.sons[0]); // [] operator for tuples requires constant expression n.sons[1] := semConstExpr(c, n.sons[1]); - if skipRange(n.sons[1].typ).kind in [tyInt..tyInt64] then begin + if skipTypes(n.sons[1].typ, {@set}[tyGenericInst, tyRange, tyOrdinal]).kind in + [tyInt..tyInt64] then begin idx := getOrdValue(n.sons[1]); if (idx >= 0) and (idx < sonsLen(arr)) then n.typ := arr.sons[int(idx)] @@ -984,12 +1016,15 @@ begin checkSonsLen(n.sons[i], 2); n.sons[i].sons[0] := semExprWithType(c, n.sons[i].sons[0]); n.sons[i].sons[1] := semExprWithType(c, n.sons[i].sons[1]); - if typ = nil then typ := skipVar(n.sons[i].sons[0].typ); + if typ = nil then + typ := skipTypes(n.sons[i].sons[0].typ, + {@set}[tyGenericInst, tyVar, tyOrdinal]); n.sons[i].typ := n.sons[i].sons[1].typ; // range node needs type too end else begin n.sons[i] := semExprWithType(c, n.sons[i]); - if typ = nil then typ := skipVar(n.sons[i].typ) + if typ = nil then + typ := skipTypes(n.sons[i].typ, {@set}[tyGenericInst, tyVar, tyOrdinal]) end end; if not isOrdinalType(typ) then begin @@ -1156,10 +1191,7 @@ begin if (s <> nil) then begin checkDeprecated(n, s); case s.kind of - skMacro: begin - include(s.flags, sfUsed); - result := semMacroExpr(c, n, s); - end; + skMacro: result := semMacroExpr(c, n, s); skTemplate: begin include(s.flags, sfUsed); // transform @@ -1234,7 +1266,6 @@ begin result := semExpr(c, result, flags) end; end; - // complex expressions nkCall, nkInfix, nkPrefix, nkPostfix, nkCommand: begin // check if it is an expression macro: checkMinSonsLen(n, 1); @@ -1242,10 +1273,7 @@ begin if (s <> nil) then begin checkDeprecated(n, s); case s.kind of - skMacro: begin - include(s.flags, sfUsed); - result := semMacroExpr(c, n, s); - end; + skMacro: result := semMacroExpr(c, n, s); skTemplate: begin include(s.flags, sfUsed); pushInfoContext(n.info); @@ -1307,7 +1335,7 @@ begin checkSonsLen(n, 1); n.sons[0] := semExprWithType(c, n.sons[0]); result := n; - case skipVarGeneric(n.sons[0].typ).kind of + case skipTypes(n.sons[0].typ, {@set}[tyGenericInst, tyVar]).kind of tyRef, tyPtr: n.typ := n.sons[0].typ.sons[0]; else liMessage(n.sons[0].info, errCircumNeedsPointer); end; diff --git a/nim/semfold.pas b/nim/semfold.pas index 261e27fd5..556dabe9b 100644 --- a/nim/semfold.pas +++ b/nim/semfold.pas @@ -1,7 +1,7 @@ // // // The Nimrod Compiler -// (c) Copyright 2008 Andreas Rumpf +// (c) Copyright 2009 Andreas Rumpf // // See the file "copying.txt", included in this // distribution, for details about the copyright. @@ -39,7 +39,7 @@ implementation function newIntNodeT(const intVal: BiggestInt; n: PNode): PNode; begin - if skipVarGenericRange(n.typ).kind = tyChar then + if skipTypes(n.typ, abstractVarRange).kind = tyChar then result := newIntNode(nkCharLit, intVal) else result := newIntNode(nkIntLit, intVal); @@ -102,7 +102,7 @@ var i: int; begin x := getInt(a); - n := a.typ.n; + n := skipTypes(a.typ, abstractInst).n; for i := 0 to sonsLen(n)-1 do begin if n.sons[i].kind <> nkSym then InternalError(a.info, 'enumValToString'); field := n.sons[i].sym; @@ -163,7 +163,7 @@ begin else result := newIntNodeT(getInt(b), n); end; mShlI, mShlI64: begin - case skipGenericRange(n.typ).kind of + case skipTypes(n.typ, abstractRange).kind of tyInt8: result := newIntNodeT(int8(getInt(a)) shl int8(getInt(b)), n); tyInt16: result := newIntNodeT(int16(getInt(a)) shl int16(getInt(b)), n); tyInt32: result := newIntNodeT(int32(getInt(a)) shl int32(getInt(b)), n); @@ -173,7 +173,7 @@ begin end end; mShrI, mShrI64: begin - case skipGenericRange(n.typ).kind of + case skipTypes(n.typ, abstractRange).kind of tyInt8: result := newIntNodeT(int8(getInt(a)) shr int8(getInt(b)), n); tyInt16: result := newIntNodeT(int16(getInt(a)) shr int16(getInt(b)), n); tyInt32: result := newIntNodeT(int32(getInt(a)) shr int32(getInt(b)), n); @@ -287,7 +287,7 @@ begin result := copyTree(a); result.typ := n.typ; end; - mNewString, mExit, mInc, ast.mDec, mAssert, mSwap, + mNewString, mExit, mInc, ast.mDec, mEcho, mAssert, mSwap, mAppendStrCh, mAppendStrStr, mAppendSeqElem, mAppendSeqSeq, mSetLengthStr, mSetLengthSeq, mNLen..mNError: begin end; else InternalError(a.info, 'evalOp(' +{&} magicToStr[m] +{&} ')'); @@ -417,7 +417,7 @@ begin end; nkCharLit..nkNilLit: result := copyNode(n); nkIfExpr: result := getConstIfExpr(module, n); - nkCall: begin + nkCall, nkCommand: begin if (n.sons[0].kind <> nkSym) then exit; s := n.sons[0].sym; if (s.kind <> skProc) then exit; @@ -440,9 +440,10 @@ begin end; mLow: result := newIntNodeT(firstOrd(n.sons[1].typ), n); mHigh: begin - if not (skipVarGeneric(n.sons[1].typ).kind in [tyOpenArray, + if not (skipTypes(n.sons[1].typ, abstractVar).kind in [tyOpenArray, tySequence, tyString]) then - result := newIntNodeT(lastOrd(skipVarGeneric(n.sons[1].typ)), n); + result := newIntNodeT(lastOrd( + skipTypes(n.sons[1].typ, abstractVar)), n); end; else begin a := getConstExpr(module, n.sons[1]); @@ -537,9 +538,9 @@ begin nkHiddenStdConv, nkHiddenSubConv, nkConv, nkCast: begin a := getConstExpr(module, n.sons[1]); if a = nil then exit; - case skipRange(n.typ).kind of + case skipTypes(n.typ, abstractRange).kind of tyInt..tyInt64: begin - case skipRange(a.typ).kind of + case skipTypes(a.typ, abstractRange).kind of tyFloat..tyFloat64: result := newIntNodeT(nsystem.toInt(getFloat(a)), n); tyChar: @@ -551,7 +552,7 @@ begin end end; tyFloat..tyFloat64: begin - case skipRange(a.typ).kind of + case skipTypes(a.typ, abstractRange).kind of tyInt..tyInt64, tyEnum, tyBool, tyChar: result := newFloatNodeT(toFloat(int(getOrdValue(a))), n); else begin diff --git a/nim/semstmts.pas b/nim/semstmts.pas index a5242b526..c8b942df8 100644 --- a/nim/semstmts.pas +++ b/nim/semstmts.pas @@ -1,7 +1,7 @@ // // // The Nimrod Compiler -// (c) Copyright 2008 Andreas Rumpf +// (c) Copyright 2009 Andreas Rumpf // // See the file "copying.txt", included in this // distribution, for details about the copyright. @@ -205,7 +205,7 @@ begin n.sons[0] := semExprWithType(c, n.sons[0]); chckCovered := false; covered := 0; - case skipVarGenericRange(n.sons[0].Typ).Kind of + case skipTypes(n.sons[0].Typ, abstractVarRange).Kind of tyInt..tyInt64, tyChar, tyEnum: chckCovered := true; tyFloat..tyFloat128, tyString: begin end else liMessage(n.info, errSelectorMustBeOfCertainTypes); @@ -302,7 +302,8 @@ begin n.sons[0] := semExprWithType(c, n.sons[0], {@set}[efLValue]); n.sons[1] := semExprWithType(c, n.sons[1]); le := n.sons[0].typ; - if (skipGeneric(le).kind <> tyVar) and not IsAssignable(n.sons[0]) then begin + if (skipTypes(le, {@set}[tyGenericInst]).kind <> tyVar) + and not IsAssignable(n.sons[0]) then begin liMessage(n.sons[0].info, errXCannotBeAssignedTo, renderTree(n.sons[0], {@set}[renderNoComments])); end @@ -410,7 +411,7 @@ begin def := nil; if not typeAllowed(typ, skVar) then liMessage(a.info, errXisNoType, typeToString(typ)); - tup := skipGeneric(typ); + tup := skipTypes(typ, {@set}[tyGenericInst]); if a.kind = nkVarTuple then begin if tup.kind <> tyTuple then liMessage(a.info, errXExpected, 'tuple'); if len-2 <> sonsLen(tup) then @@ -511,7 +512,7 @@ begin n.sons[len-2] := countupNode; end; n.sons[len-2] := semExprWithType(c, n.sons[len-2]); - iter := skipGeneric(n.sons[len-2].typ); + iter := skipTypes(n.sons[len-2].typ, {@set}[tyGenericInst]); if iter.kind <> tyTuple then begin if len <> 3 then liMessage(n.info, errWrongNumberOfVariables); v := newSymS(skForVar, n.sons[0], c); @@ -742,6 +743,17 @@ begin end end; +procedure semBorrow(c: PContext; n: PNode; s: PSym); +var + b: PSym; +begin + // search for the correct alias: + b := SearchForBorrowProc(c, s, c.tab.tos-2); + if b = nil then liMessage(n.info, errNoSymbolToBorrowFromFound); + // store the alias: + n.sons[codePos] := newSymNode(b); +end; + function semIterator(c: PContext; n: PNode): PNode; var s: PSym; @@ -774,6 +786,8 @@ begin pragmaIterator(c, s, n.sons[pragmasPos]); s.options := gOptions; if n.sons[codePos] <> nil then begin + if sfBorrow in s.flags then + liMessage(n.info, errImplOfXNotAllowed, s.name.s); if n.sons[genericParamsPos] = nil then begin c.p := newProcCon(s); openScope(c.tab); @@ -784,6 +798,8 @@ begin n.sons[codePos] := resolveGenericParams(c, n.sons[codePos]); end end + else if (sfBorrow in s.flags) then + semBorrow(c, n, s) else liMessage(n.info, errIteratorNeedsImplementation); closeScope(c.tab); @@ -849,7 +865,7 @@ begin s.options := gOptions; if n.sons[codePos] <> nil then begin if sfImportc in s.flags then - liMessage(n.sons[codePos].info, errImportedProcCannotHaveImpl); + liMessage(n.sons[codePos].info, errImplOfXNotAllowed, s.name.s); c.p := newProcCon(s); addResult(c, s.typ.sons[0], n.info); n.sons[codePos] := semStmtScope(c, n.sons[codePos]); @@ -937,8 +953,8 @@ begin s.options := gOptions; if n.sons[codePos] <> nil then begin - if sfImportc in s.flags then - liMessage(n.sons[codePos].info, errImportedProcCannotHaveImpl); + if [sfImportc, sfBorrow] * s.flags <> [] then + liMessage(n.sons[codePos].info, errImplOfXNotAllowed, s.name.s); if n.sons[genericParamsPos] = nil then begin c.p := newProcCon(s); addResult(c, s.typ.sons[0], n.info); @@ -952,7 +968,9 @@ begin else begin if proto <> nil then liMessage(n.info, errImplOfXexpected, proto.name.s); - if not (sfImportc in s.flags) then Include(s.flags, sfForward); + if [sfImportc, sfBorrow] * s.flags = [] then Include(s.flags, sfForward) + else if sfBorrow in s.flags then + semBorrow(c, n, s); end; closeScope(c.tab); // close scope for parameters popOwner(); diff --git a/nim/semtypes.pas b/nim/semtypes.pas index 014ff0216..c968d4b72 100644 --- a/nim/semtypes.pas +++ b/nim/semtypes.pas @@ -1,7 +1,7 @@ // // // The Nimrod Compiler -// (c) Copyright 2008 Andreas Rumpf +// (c) Copyright 2009 Andreas Rumpf // // See the file "copying.txt", included in this // distribution, for details about the copyright. @@ -140,6 +140,15 @@ begin liMessage(n.info, errXExpectsOneTypeParam, 'var'); end; +function semAbstract(c: PContext; n: PNode; prev: PType): PType; +begin + result := newOrPrevType(tyAbstract, prev, c); + if sonsLen(n) = 1 then + addSon(result, semTypeNode(c, n.sons[0], nil)) + else + liMessage(n.info, errXExpectsOneTypeParam, 'abstract'); +end; + function semRangeAux(c: PContext; n: PNode; prev: PType): PType; var a, b: PNode; @@ -202,6 +211,23 @@ begin liMessage(n.info, errArrayExpectsTwoTypeParams); end; +function semOrdinal(c: PContext; n: PNode; prev: PType): PType; +var + base: PType; +begin + result := newOrPrevType(tyOrdinal, prev, c); + if sonsLen(n) = 2 then begin + base := semTypeNode(c, n.sons[1], nil); + if base.kind <> tyGenericParam then begin + if not isOrdinalType(base) then + liMessage(n.sons[1].info, errOrdinalTypeExpected); + end; + addSon(result, base); + end + else + liMessage(n.info, errXExpectsOneTypeParam, 'ordinal'); +end; + function semTypeIdent(c: PContext; n: PNode): PSym; begin result := qualifiedLookup(c, n, true); @@ -441,7 +467,7 @@ begin internalError('semRecordCase: dicriminant is no symbol'); include(a.sons[0].sym.flags, sfDiscriminant); covered := 0; - typ := skipVarGeneric(a.sons[0].Typ); + typ := skipTypes(a.sons[0].Typ, abstractVar); if not isOrdinalType(typ) then liMessage(n.info, errSelectorMustBeOrdinal); if firstOrd(typ) < 0 then @@ -740,6 +766,7 @@ begin mOpenArray: result := semContainer(c, n, tyOpenArray, 'openarray', prev); mRange: result := semRange(c, n, prev); mSet: result := semSet(c, n, prev); + mOrdinal: result := semOrdinal(c, n, prev); mSeq: result := semContainer(c, n, tySequence, 'seq', prev); else result := semGeneric(c, n, s, prev); end @@ -774,6 +801,7 @@ begin nkRefTy: result := semAnyRef(c, n, tyRef, 'ref', prev); nkPtrTy: result := semAnyRef(c, n, tyPtr, 'ptr', prev); nkVarTy: result := semVarType(c, n, prev); + nkAbstractTy: result := semAbstract(c, n, prev); nkProcTy: begin checkSonsLen(n, 2); result := semProcTypeNode(c, n.sons[0], prev); @@ -821,7 +849,6 @@ begin addSon(m.typ, getSysType(tyChar)); end; mPointer: setMagicType(m, tyPointer, ptrSize); - mAnyEnum: setMagicType(m, tyAnyEnum, 1); mEmptySet: begin setMagicType(m, tySet, 1); addSon(m.typ, newTypeS(tyEmpty, c)); @@ -832,7 +859,7 @@ begin exit end; mNil: setMagicType(m, tyNil, ptrSize); - mArray, mOpenArray, mRange, mSet, mSeq: exit; + mArray, mOpenArray, mRange, mSet, mSeq, mOrdinal: exit; else liMessage(m.info, errTypeExpected); end; //registerSysType(m.typ); diff --git a/nim/sigmatch.pas b/nim/sigmatch.pas index 5195de26c..d95745e0c 100644 --- a/nim/sigmatch.pas +++ b/nim/sigmatch.pas @@ -122,7 +122,7 @@ begin if a.kind = f.kind then result := isEqual else begin - k := skipRange(a).kind; + k := skipTypes(a, {@set}[tyRange]).kind; if k = f.kind then result := isSubtype else if (f.kind = tyInt) and (k in [tyInt..tyInt32]) then @@ -141,7 +141,7 @@ begin if a.kind = f.kind then result := isEqual else begin - k := skipRange(a).kind; + k := skipTypes(a, {@set}[tyRange]).kind; if k = f.kind then result := isSubtype else if (k >= tyFloat) and (k <= tyFloat128) then @@ -203,7 +203,8 @@ begin // is a subtype of f? result := isNone; assert(f <> nil); assert(a <> nil); - if (a.kind = tyGenericInst) and (skipVar(f).kind <> tyGeneric) then begin + if (a.kind = tyGenericInst) and + (skipTypes(f, {@set}[tyVar]).kind <> tyGeneric) then begin result := typeRel(mapping, f, lastSon(a)); exit end; @@ -214,18 +215,19 @@ begin // is a subtype of f? case f.kind of tyEnum: begin if (a.kind = f.kind) and (a.id = f.id) then result := isEqual - else if (skipRange(a).id = f.id) then result := isSubtype + else if (skipTypes(a, {@set}[tyRange]).id = f.id) then result := isSubtype end; tyBool, tyChar: begin if (a.kind = f.kind) then result := isEqual - else if skipRange(a).kind = f.kind then result := isSubtype + else if skipTypes(a, {@set}[tyRange]).kind = f.kind then + result := isSubtype end; tyRange: begin if (a.kind = f.kind) then begin result := typeRel(mapping, base(a), base(f)); if result < isGeneric then result := isNone end - else if skipRange(f).kind = a.kind then + else if skipTypes(f, {@set}[tyRange]).kind = a.kind then result := isConvertible // a convertible to f end; tyInt: result := handleRange(f, a, tyInt8, tyInt32); @@ -311,6 +313,13 @@ begin // is a subtype of f? else begin end end end; + tyOrdinal: begin + if isOrdinalType(a) then begin + if a.kind = tyOrdinal then x := a.sons[0] else x := a; + result := typeRel(mapping, f.sons[0], x); + if result < isGeneric then result := isNone + end + end; tyForward: InternalError('forward type in typeRel()'); tyNil: begin if a.kind = f.kind then result := isEqual @@ -324,6 +333,9 @@ begin // is a subtype of f? else if isObjectSubtype(a, f) then result := isSubtype end end; + tyAbstract: begin + if (a.kind = tyAbstract) and (a.id = f.id) then result := isEqual; + end; tySet: begin if a.kind = tySet then begin if (f.sons[0].kind <> tyGenericParam) and @@ -418,8 +430,8 @@ begin // is a subtype of f? tyPtr: if a.sons[0].kind = tyChar then result := isConvertible; tyArray: begin if (firstOrd(a.sons[0]) = 0) - and (skipRange(a.sons[0]).kind in [tyInt..tyInt64]) - and (a.sons[1].kind = tyChar) then + and (skipTypes(a.sons[0], {@set}[tyRange]).kind in [tyInt..tyInt64]) + and (a.sons[1].kind = tyChar) then result := isConvertible; end else begin end @@ -429,14 +441,6 @@ begin // is a subtype of f? tyEmpty: begin if a.kind = tyEmpty then result := isEqual; end; - tyAnyEnum: begin - case a.kind of - tyRange: result := typeRel(mapping, f, base(a)); - tyEnum: result := isSubtype; - tyAnyEnum: result := isEqual; - else begin end - end - end; tyGenericInst: begin result := typeRel(mapping, lastSon(f), a); end; @@ -572,7 +576,7 @@ begin result := copyTree(arg); result.typ := getInstantiatedType(c, arg, m, f); // BUG: f may not be the right key! - if (skipVarGeneric(result.typ).kind in [tyTuple, tyOpenArray]) then + if (skipTypes(result.typ, abstractVar).kind in [tyTuple, tyOpenArray]) then // BUGFIX: must pass length implicitely result := implicitConv(nkHiddenStdConv, f, copyTree(arg), m, c); // BUGFIX: use ``result.typ`` and not `f` here @@ -580,7 +584,7 @@ begin isEqual: begin inc(m.exactMatches); result := copyTree(arg); - if (skipVarGeneric(f).kind in [tyTuple, tyOpenArray]) then + if (skipTypes(f, abstractVar).kind in [tyTuple, tyOpenArray]) then // BUGFIX: must pass length implicitely result := implicitConv(nkHiddenStdConv, f, copyTree(arg), m, c); end; @@ -679,7 +683,7 @@ begin if f >= formalLen then begin // too many arguments? if tfVarArgs in m.callee.flags then begin // is ok... but don't increment any counters... - if skipVarGeneric(n.sons[a].typ).kind = tyString then + if skipTypes(n.sons[a].typ, abstractVar).kind = tyString then // conversion to cstring addSon(m.call, implicitConv(nkHiddenStdConv, getSysType(tyCString), copyTree(n.sons[a]), m, c)) diff --git a/nim/transf.pas b/nim/transf.pas index 476ee4c33..b1812d52c 100644 --- a/nim/transf.pas +++ b/nim/transf.pas @@ -1,7 +1,7 @@ // // // The Nimrod Compiler -// (c) Copyright 2008 Andreas Rumpf +// (c) Copyright 2009 Andreas Rumpf // // See the file "copying.txt", included in this // distribution, for details about the copyright. @@ -80,7 +80,8 @@ function newTemp(c: PTransf; typ: PType; const info: TLineInfo): PSym; begin result := newSym(skTemp, getIdent(genPrefix), getCurrOwner(c)); result.info := info; - result.typ := skipGeneric(typ); + result.typ := skipTypes(typ, {@set}[tyGenericInst]); + // XXX really correct? maybe we need tyGenericInst for generic instantion? include(result.flags, sfFromGeneric); end; @@ -148,23 +149,34 @@ end; function transformSym(c: PTransf; n: PNode): PNode; var tc: PTransCon; + b: PNode; begin if (n.kind <> nkSym) then internalError(n.info, 'transformSym'); tc := c.transCon; + if sfBorrow in n.sym.flags then begin + // simply exchange the symbol: + b := n.sym.ast.sons[codePos]; + if b.kind <> nkSym then + internalError(n.info, 'wrong AST for borrowed symbol'); + b := newSymNode(b.sym); + b.info := n.info; + end + else + b := n; //writeln('transformSym', n.sym.id : 5); while tc <> nil do begin - result := IdNodeTableGet(tc.mapping, n.sym); + result := IdNodeTableGet(tc.mapping, b.sym); if result <> nil then exit; //write('not found in: '); //writeIdNodeTable(tc.mapping); tc := tc.next end; - result := n; - case n.sym.kind of + result := b; + case b.sym.kind of skConst, skEnumField: begin // BUGFIX: skEnumField was missing - if not (skipGeneric(n.sym.typ).kind in ConstantDataTypes) then begin - result := getConstExpr(c.module, n); - if result = nil then InternalError(n.info, 'transformSym: const'); + if not (skipTypes(b.sym.typ, abstractInst).kind in ConstantDataTypes) then begin + result := getConstExpr(c.module, b); + if result = nil then InternalError(b.info, 'transformSym: const'); end end else begin end @@ -254,7 +266,7 @@ var begin result := newNodeI(nkStmtList, n.info); e := n.sons[0]; - if skipGeneric(e.typ).kind = tyTuple then begin + if skipTypes(e.typ, {@set}[tyGenericInst]).kind = tyTuple then begin e := skipConv(e); if e.kind = nkPar then begin for i := 0 to sonsLen(e)-1 do begin @@ -366,8 +378,8 @@ begin n.sons[1] := transform(c, n.sons[1]); result := n; // numeric types need range checks: - dest := skipVarGenericRange(n.typ); - source := skipVarGenericRange(n.sons[1].typ); + dest := skipTypes(n.typ, abstractVarRange); + source := skipTypes(n.sons[1].typ, abstractVarRange); case dest.kind of tyInt..tyInt64, tyEnum, tyChar, tyBool: begin if (firstOrd(dest) <= firstOrd(source)) and @@ -381,16 +393,16 @@ begin result := newNodeIT(nkChckRange64, n.info, n.typ) else result := newNodeIT(nkChckRange, n.info, n.typ); - dest := skipVarGeneric(n.typ); + dest := skipTypes(n.typ, abstractVar); addSon(result, n.sons[1]); addSon(result, newIntTypeNode(nkIntLit, firstOrd(dest), source)); addSon(result, newIntTypeNode(nkIntLit, lastOrd(dest), source)); end end; tyFloat..tyFloat128: begin - if skipVarGeneric(n.typ).kind = tyRange then begin + if skipTypes(n.typ, abstractVar).kind = tyRange then begin result := newNodeIT(nkChckRangeF, n.info, n.typ); - dest := skipVarGeneric(n.typ); + dest := skipTypes(n.typ, abstractVar); addSon(result, n.sons[1]); addSon(result, copyTree(dest.n.sons[0])); addSon(result, copyTree(dest.n.sons[1])); @@ -413,8 +425,8 @@ begin end; end; tyRef, tyPtr: begin - dest := skipPtrsGeneric(dest); - source := skipPtrsGeneric(source); + dest := skipTypes(dest, abstractPtrs); + source := skipTypes(source, abstractPtrs); if source.kind = tyObject then begin diff := inheritanceDiff(dest, source); if diff < 0 then begin @@ -444,7 +456,7 @@ begin tyArray, tySeq: begin if skipGeneric(dest end; *) - tyGenericParam, tyAnyEnum: result := n.sons[1]; + tyGenericParam, tyOrdinal: result := n.sons[1]; // happens sometimes for generated assignments, etc. else begin end end; @@ -465,7 +477,7 @@ function putArgInto(arg: PNode; formal: PType): TPutArgInto; var i: int; begin - if skipGeneric(formal).kind = tyOpenArray then begin + if skipTypes(formal, abstractInst).kind = tyOpenArray then begin result := paDirectMapping; // XXX really correct? // what if ``arg`` has side-effects? exit @@ -480,7 +492,7 @@ begin result := paDirectMapping; end; else begin - if skipGeneric(formal).kind = tyVar then + if skipTypes(formal, abstractInst).kind = tyVar then result := paVarAsgn else result := paFastAsgn @@ -516,7 +528,7 @@ begin pushTransCon(c, newC); for i := 1 to sonsLen(call)-1 do begin arg := skipPassAsOpenArray(transform(c, call.sons[i])); - formal := skipGeneric(newC.owner.typ).n.sons[i].sym; + formal := skipTypes(newC.owner.typ, abstractInst).n.sons[i].sym; //if IdentEq(newc.Owner.name, 'items') then // liMessage(arg.info, warnUser, 'items: ' + nodeKindToStr[arg.kind]); case putArgInto(arg, formal.typ) of @@ -529,7 +541,7 @@ begin IdNodeTablePut(newC.mapping, formal, newSymNode(temp)); end; paVarAsgn: begin - assert(skipGeneric(formal.typ).kind = tyVar); + assert(skipTypes(formal.typ, abstractInst).kind = tyVar); InternalError(arg.info, 'not implemented: pass to var parameter'); end; end; @@ -820,13 +832,15 @@ var begin result := n; if n = nil then exit; + //if ToLinenumber(n.info) = 32 then + // MessageOut(RenderTree(n)); case n.kind of nkSym: begin result := transformSym(c, n); exit end; nkEmpty..pred(nkSym), succ(nkSym)..nkNilLit: begin - // nothing to be done for leafs + // nothing to be done for leaves end; nkBracketExpr: result := transformArrayAccess(c, n); nkLambda: result := transformLambda(c, n); diff --git a/nim/transtmp.pas b/nim/transtmp.pas index cfec21c98..77ba157f3 100644 --- a/nim/transtmp.pas +++ b/nim/transtmp.pas @@ -140,7 +140,7 @@ begin addSon(father, newAsgnStmt(dest, src)); end end; - nkCall: begin + nkCall, nkCommand: begin end; diff --git a/nim/trees.pas b/nim/trees.pas index d271bfae8..4df85f6bb 100644 --- a/nim/trees.pas +++ b/nim/trees.pas @@ -144,7 +144,7 @@ end; function getOpSym(op: PNode): PSym; begin - if not (op.kind in [nkCall, nkGenericCall, nkHiddenCallConv]) then + if not (op.kind in [nkCall, nkGenericCall, nkHiddenCallConv, nkCommand]) then result := nil else begin if (sonsLen(op) <= 0) then InternalError(op.info, 'getOpSym'); @@ -158,7 +158,7 @@ end; function getMagic(op: PNode): TMagic; begin case op.kind of - nkCall, nkHiddenCallConv: begin + nkCall, nkHiddenCallConv, nkCommand: begin case op.sons[0].Kind of nkSym: begin result := op.sons[0].sym.magic; diff --git a/nim/types.pas b/nim/types.pas index af19a1671..b4558fe82 100644 --- a/nim/types.pas +++ b/nim/types.pas @@ -48,6 +48,7 @@ function mutateType(t: PType; iter: TTypeMutator; closure: PObject): PType; function SameType(x, y: PType): Boolean; function SameTypeOrNil(a, b: PType): Boolean; +function equalOrAbstractOf(x, y: PType): bool; type TParamsEquality = (paramsNotEqual, // parameters are not equal @@ -64,6 +65,7 @@ function equalParams(a, b: PNode): TParamsEquality; function isOrdinalType(t: PType): Boolean; function enumHasWholes(t: PType): Boolean; +(* function skipRange(t: PType): PType; function skipGeneric(t: PType): PType; function skipGenericRange(t: PType): PType; @@ -71,6 +73,16 @@ function skipVar(t: PType): PType; function skipVarGeneric(t: PType): PType; function skipVarGenericRange(t: PType): PType; function skipPtrsGeneric(t: PType): PType; +*) + +const + abstractPtrs = {@set}[tyVar, tyPtr, tyRef, tyGenericInst, tyAbstract, tyOrdinal]; + abstractVar = {@set}[tyVar, tyGenericInst, tyAbstract, tyOrdinal]; + abstractRange = {@set}[tyGenericInst, tyRange, tyAbstract, tyOrdinal]; + abstractVarRange = {@set}[tyGenericInst, tyRange, tyVar, tyAbstract, tyOrdinal]; + abstractInst = {@set}[tyGenericInst, tyAbstract, tyOrdinal]; + +function skipTypes(t: PType; kinds: TTypeKinds): PType; function elemType(t: PType): PType; @@ -171,7 +183,7 @@ begin result := false; if a.kind = tyArray then if (firstOrd(a.sons[0]) = 0) - and (skipRange(a.sons[0]).kind in [tyInt..tyInt64]) + and (skipTypes(a.sons[0], {@set}[tyRange]).kind in [tyInt..tyInt64]) and (a.sons[1].kind = tyChar) then result := true end; @@ -200,7 +212,7 @@ function elemType(t: PType): PType; begin assert(t <> nil); case t.kind of - tyGenericInst: result := elemType(lastSon(t)); + tyGenericInst, tyAbstract: result := elemType(lastSon(t)); tyArray, tyArrayConstr: result := t.sons[1]; else result := t.sons[0]; end; @@ -259,11 +271,17 @@ begin result := lastSon(result); end; +function skipTypes(t: PType; kinds: TTypeKinds): PType; +begin + result := t; + while result.kind in kinds do result := lastSon(result); +end; + function isOrdinalType(t: PType): Boolean; begin assert(t <> nil); result := (t.Kind in [tyChar, tyInt..tyInt64, tyBool, tyEnum]) - or (t.Kind = tyRange) and isOrdinalType(t.sons[0]); + or (t.Kind in [tyRange, tyOrdinal]) and isOrdinalType(t.sons[0]); end; function enumHasWholes(t: PType): Boolean; @@ -380,7 +398,8 @@ begin if not result then result := searchTypeNodeForAux(t.n, predicate, marker); end; - tyGenericInst: result := searchTypeForAux(lastSon(t), predicate, marker); + tyGenericInst, tyAbstract: + result := searchTypeForAux(lastSon(t), predicate, marker); tyArray, tyArrayConstr, tySet, tyTuple: begin for i := 0 to sonsLen(t)-1 do begin result := searchTypeForAux(t.sons[i], predicate, marker); @@ -438,7 +457,8 @@ begin if result = frNone then if isObjectWithTypeFieldPredicate(t) then result := frHeader end; - tyGenericInst: result := analyseObjectWithTypeFieldAux(lastSon(t), marker); + tyGenericInst, tyAbstract: + result := analyseObjectWithTypeFieldAux(lastSon(t), marker); tyArray, tyArrayConstr, tyTuple: begin for i := 0 to sonsLen(t)-1 do begin res := analyseObjectWithTypeFieldAux(t.sons[i], marker); @@ -511,7 +531,7 @@ begin result := false; if t = nil then exit; if tfAcyclic in t.flags then exit; - case skipGeneric(t).kind of + case skipTypes(t, abstractInst).kind of tyTuple, tyObject, tyRef, tySequence, tyArray, tyArrayConstr, tyOpenArray: begin if not IntSetContainsOrIncl(marker, t.id) then begin @@ -597,8 +617,8 @@ function TypeToString(typ: PType; prefer: TPreferedDesc = preferName): string; const typeToStr: array [TTypeKind] of string = ( 'None', 'bool', 'Char', 'empty', 'Array Constructor [$1]', 'nil', - 'Generic', 'GenericInst', 'GenericParam', - 'enum', 'anyenum', + 'Generic', 'GenericInst', 'GenericParam', 'abstract $1', + 'enum', 'ordinal[$1]', 'array[$1, $2]', 'object', 'tuple', 'set[$1]', 'range[$1]', 'ptr ', 'ref ', 'var ', 'seq[$1]', 'proc', 'pointer', 'OpenArray[$1]', 'string', 'CString', 'Forward', @@ -631,8 +651,10 @@ begin result := 'Array constructor[' +{&} rangeToStr(t.sons[0].n) +{&} ', ' +{&} typeToString(t.sons[1]) +{&} ']'; tySequence: result := 'seq[' +{&} typeToString(t.sons[0]) +{&} ']'; + tyOrdinal: result := 'ordinal[' +{&} typeToString(t.sons[0]) +{&} ']'; tySet: result := 'set[' +{&} typeToString(t.sons[0]) +{&} ']'; tyOpenArray: result := 'openarray[' +{&} typeToString(t.sons[0]) +{&} ']'; + tyAbstract: result := 'abstract ' +{&} typeToString(t.sons[0], preferName); tyTuple: begin // we iterate over t.sons here, because t.n may be nil result := 'tuple['; @@ -718,7 +740,7 @@ begin result := t.n.sons[0].sym.position; end; end; - tyGenericInst: result := firstOrd(lastSon(t)); + tyGenericInst, tyAbstract: result := firstOrd(lastSon(t)); else begin InternalError('invalid kind for first(' +{&} typeKindToStr[t.kind] +{&} ')'); @@ -754,7 +776,7 @@ begin assert(t.n.sons[sonsLen(t.n)-1].kind = nkSym); result := t.n.sons[sonsLen(t.n)-1].sym.position; end; - tyGenericInst: result := firstOrd(lastSon(t)); + tyGenericInst, tyAbstract: result := firstOrd(lastSon(t)); else begin InternalError('invalid kind for last(' +{&} typeKindToStr[t.kind] +{&} ')'); @@ -767,6 +789,7 @@ function lengthOrd(t: PType): biggestInt; begin case t.kind of tyInt64, tyInt32, tyInt: result := lastOrd(t); + tyAbstract: result := lengthOrd(t.sons[0]); else result := lastOrd(t) - firstOrd(t) + 1; end end; @@ -855,7 +878,7 @@ begin SameLiteral(a.sons[1], b.sons[1]) end; -function sameTuple(a, b: PType): boolean; +function sameTuple(a, b: PType; AbstractOf: bool): boolean; // two tuples are equivalent iff the names, types and positions are the same; // however, both types may not have any field names (t.n may be nil) which // complicates the matter a bit. @@ -866,7 +889,10 @@ begin if sonsLen(a) = sonsLen(b) then begin result := true; for i := 0 to sonsLen(a)-1 do begin - result := SameType(a.sons[i], b.sons[i]); + if AbstractOf then + result := equalOrAbstractOf(a.sons[i], b.sons[i]) + else + result := SameType(a.sons[i], b.sons[i]); if not result then exit end; if (a.n <> nil) and (b.n <> nil) then begin @@ -891,8 +917,8 @@ var a, b: PType; begin if x = y then begin result := true; exit end; - a := skipGeneric(x); - b := skipGeneric(y); + a := skipTypes(x, {@set}[tyGenericInst]); + b := skipTypes(y, {@set}[tyGenericInst]); assert(a <> nil); assert(b <> nil); if a.kind <> b.kind then begin result := false; exit end; @@ -900,13 +926,13 @@ begin tyEmpty, tyChar, tyBool, tyNil, tyPointer, tyString, tyCString, tyInt..tyFloat128: result := true; - tyEnum, tyForward, tyObject: + tyEnum, tyForward, tyObject, tyAbstract: result := (a.id = b.id); tyTuple: - result := sameTuple(a, b); + result := sameTuple(a, b, false); tyGenericInst: result := sameType(lastSon(a), lastSon(b)); - tyGenericParam, tyGeneric, tySequence, + tyGenericParam, tyGeneric, tySequence, tyOrdinal, tyOpenArray, tySet, tyRef, tyPtr, tyVar, tyArrayConstr, tyArray, tyProc: begin if sonsLen(a) = sonsLen(b) then begin @@ -926,7 +952,56 @@ begin and SameValue(a.n.sons[0], b.n.sons[0]) and SameValue(a.n.sons[1], b.n.sons[1]) end; - tyNone, tyAnyEnum: result := false; + tyNone: result := false; + end +end; + +function equalOrAbstractOf(x, y: PType): bool; +var + i: int; + a, b: PType; +begin + if x = y then begin result := true; exit end; + if (x = nil) or (y = nil) then begin result := false; exit end; + a := skipTypes(x, {@set}[tyGenericInst]); + b := skipTypes(y, {@set}[tyGenericInst]); + assert(a <> nil); + assert(b <> nil); + if a.kind <> b.kind then begin + if a.kind = tyAbstract then a := a.sons[0]; + if a.kind <> b.kind then begin result := false; exit end + end; + case a.Kind of + tyEmpty, tyChar, tyBool, tyNil, tyPointer, tyString, tyCString, + tyInt..tyFloat128: + result := true; + tyEnum, tyForward, tyObject, tyAbstract: + result := (a.id = b.id); + tyTuple: + result := sameTuple(a, b, true); + tyGenericInst: + result := equalOrAbstractOf(lastSon(a), lastSon(b)); + tyGenericParam, tyGeneric, tySequence, tyOrdinal, + tyOpenArray, tySet, tyRef, tyPtr, tyVar, tyArrayConstr, + tyArray, tyProc: begin + if sonsLen(a) = sonsLen(b) then begin + result := true; + for i := 0 to sonsLen(a)-1 do begin + result := equalOrAbstractOf(a.sons[i], b.sons[i]); + if not result then exit + end; + if result and (a.kind = tyProc) then + result := a.callConv = b.callConv + end + else + result := false; + end; + tyRange: begin + result := equalOrAbstractOf(a.sons[0], b.sons[0]) + and SameValue(a.n.sons[0], b.n.sons[0]) + and SameValue(a.n.sons[1], b.n.sons[1]) + end; + tyNone: result := false; end end; @@ -963,9 +1038,9 @@ begin // if we have already checked the type, return true, because we stop the // evaluation if something is wrong: if IntSetContainsOrIncl(marker, t.id) then exit; - case skipGeneric(t).kind of + case skipTypes(t, abstractInst).kind of tyVar: begin - case skipGeneric(t.sons[0]).kind of + case skipTypes(t.sons[0], abstractInst).kind of tyVar: result := false; // ``var var`` is always an invalid type: tyOpenArray: result := (kind = skParam) and typeAllowedAux(marker, t.sons[0], kind); @@ -985,9 +1060,11 @@ begin tyEmpty, tyNil: result := kind = skConst; tyString, tyBool, tyChar, tyEnum, tyInt..tyFloat128, tyCString, tyPointer: result := true; - tyAnyEnum: result := kind = skParam; - tyGenericInst: result := typeAllowedAux(marker, lastSon(t), kind); - tyRange: result := skipGeneric(t.sons[0]).kind in + tyOrdinal: result := kind = skParam; + tyGenericInst, tyAbstract: + result := typeAllowedAux(marker, lastSon(t), kind); + tyRange: + result := skipTypes(t.sons[0], abstractInst).kind in [tyChar, tyEnum, tyInt..tyFloat128]; tyOpenArray: result := (kind = skParam) and typeAllowedAux(marker, t.sons[0], skVar); @@ -1166,7 +1243,7 @@ begin if a < maxAlign then a := maxAlign; result := align(result, a); end; - tyGenericInst: begin + tyGenericInst, tyAbstract: begin result := computeSizeAux(lastSon(typ), a); end; else begin diff --git a/nim/wordrecg.pas b/nim/wordrecg.pas index 7957d354b..cd31a64e4 100644 --- a/nim/wordrecg.pas +++ b/nim/wordrecg.pas @@ -39,20 +39,20 @@ type // i = i + 1 //cog.out(idents) //]]] - wAddr, wAnd, wAs, wAsm, - wBlock, wBreak, wCase, wCast, - wConst, wContinue, wConverter, wDiscard, - wDiv, wElif, wElse, wEnd, - wEnum, wExcept, wException, wFinally, - wFor, wFrom, wGeneric, wIf, - wImplies, wImport, wIn, wInclude, - wIs, wIsnot, wIterator, wLambda, - wMacro, wMethod, wMod, wNil, - wNot, wNotin, wObject, wOf, - wOr, wOut, wProc, wPtr, - wRaise, wRef, wReturn, wShl, - wShr, wTemplate, wTry, wTuple, - wType, wVar, wWhen, wWhere, + wAbstract, wAddr, wAnd, wAs, + wAsm, wBlock, wBreak, wCase, + wCast, wConst, wContinue, wConverter, + wDiscard, wDiv, wElif, wElse, + wEnd, wEnum, wExcept, wException, + wFinally, wFor, wFrom, wGeneric, + wIf, wImplies, wImport, wIn, + wInclude, wIs, wIsnot, wIterator, + wLambda, wMacro, wMethod, wMod, + wNil, wNot, wNotin, wObject, + wOf, wOr, wOut, wProc, + wPtr, wRaise, wRef, wReturn, + wShl, wShr, wTemplate, wTry, + wTuple, wType, wVar, wWhen, wWhile, wWith, wWithout, wXor, wYield, //[[[end]]] @@ -78,7 +78,7 @@ type wApp, wConsole, wGui, wPassc, wT, wPassl, wL, wListcmd, wGendoc, wGenmapping, wOs, wCpu, wGenerate, wG, wC, wCpp, - wYaml, wRun, wR, wVerbosity, wV, wHelp, + wBorrow, wRun, wR, wVerbosity, wV, wHelp, wH, wSymbolFiles, wFieldChecks, wX, wVersion, wAdvanced, wSkipcfg, wSkipProjCfg, wCc, wGenscript, wCheckPoint, wCheckPoints, wMaxErr, wExpr, wStmt, wTypeDesc, @@ -113,20 +113,20 @@ const //[[[cog //cog.out(strings) //]]] - 'addr', 'and', 'as', 'asm', - 'block', 'break', 'case', 'cast', - 'const', 'continue', 'converter', 'discard', - 'div', 'elif', 'else', 'end', - 'enum', 'except', 'exception', 'finally', - 'for', 'from', 'generic', 'if', - 'implies', 'import', 'in', 'include', - 'is', 'isnot', 'iterator', 'lambda', - 'macro', 'method', 'mod', 'nil', - 'not', 'notin', 'object', 'of', - 'or', 'out', 'proc', 'ptr', - 'raise', 'ref', 'return', 'shl', - 'shr', 'template', 'try', 'tuple', - 'type', 'var', 'when', 'where', + 'abstract', 'addr', 'and', 'as', + 'asm', 'block', 'break', 'case', + 'cast', 'const', 'continue', 'converter', + 'discard', 'div', 'elif', 'else', + 'end', 'enum', 'except', 'exception', + 'finally', 'for', 'from', 'generic', + 'if', 'implies', 'import', 'in', + 'include', 'is', 'isnot', 'iterator', + 'lambda', 'macro', 'method', 'mod', + 'nil', 'not', 'notin', 'object', + 'of', 'or', 'out', 'proc', + 'ptr', 'raise', 'ref', 'return', + 'shl', 'shr', 'template', 'try', + 'tuple', 'type', 'var', 'when', 'while', 'with', 'without', 'xor', 'yield', //[[[end]]] @@ -152,7 +152,7 @@ const 'app', 'console', 'gui', 'passc', 't'+'', 'passl', 'l'+'', 'listcmd', 'gendoc', 'genmapping', 'os', 'cpu', 'generate', 'g'+'', 'c'+'', 'cpp', - 'yaml', 'run', 'r'+'', 'verbosity', 'v'+'', 'help', + 'borrow', 'run', 'r'+'', 'verbosity', 'v'+'', 'help', 'h'+'', 'symbolfiles', 'fieldchecks', 'x'+'', 'version', 'advanced', 'skipcfg', 'skipprojcfg', 'cc', 'genscript', 'checkpoint', 'checkpoints', 'maxerr', 'expr', 'stmt', 'typedesc', |