diff options
author | Andreas Rumpf <rumpf_a@web.de> | 2009-05-20 10:44:24 +0200 |
---|---|---|
committer | Andreas Rumpf <rumpf_a@web.de> | 2009-05-20 10:44:24 +0200 |
commit | ce88dc3e67436939b03f97e624c11ca6058fedce (patch) | |
tree | 7619ef68227aef88d8a4e6d8792486d27531825e /nim | |
parent | 44a874e3a43f88c6798c9eef3dad0bb4ad9ab97e (diff) | |
download | Nim-ce88dc3e67436939b03f97e624c11ca6058fedce.tar.gz |
some fixes for DMC
Diffstat (limited to 'nim')
-rw-r--r-- | nim/ast.pas | 2378 | ||||
-rw-r--r-- | nim/ccgexprs.pas | 31 | ||||
-rw-r--r-- | nim/ccgstmts.pas | 21 | ||||
-rw-r--r-- | nim/ccgtypes.pas | 14 | ||||
-rw-r--r-- | nim/msgs.pas | 1102 | ||||
-rw-r--r-- | nim/semfold.pas | 35 | ||||
-rw-r--r-- | nim/sigmatch.pas | 2 | ||||
-rw-r--r-- | nim/transf.pas | 10 |
8 files changed, 1806 insertions, 1787 deletions
diff --git a/nim/ast.pas b/nim/ast.pas index 0c3137b2b..aa83af4ed 100644 --- a/nim/ast.pas +++ b/nim/ast.pas @@ -1,70 +1,70 @@ -// -// -// The Nimrod Compiler -// (c) Copyright 2008 Andreas Rumpf -// -// See the file "copying.txt", included in this -// distribution, for details about the copyright. -// -unit ast; - -// abstract syntax tree + symbol table - -interface - -{$include 'config.inc'} - -uses - nsystem, charsets, msgs, nhashes, - nversion, options, strutils, crc, ropes, idents, lists; - -const - ImportTablePos = 0; - ModuleTablePos = 1; - -type - TCallingConvention = ( - ccDefault, // proc has no explicit calling convention - ccStdCall, // procedure is stdcall - ccCDecl, // cdecl - ccSafeCall, // safecall - ccSysCall, // system call - ccInline, // proc should be inlined - ccNoInline, // proc should not be inlined - ccFastCall, // fastcall (pass parameters in registers) - ccClosure, // proc has a closure - ccNoConvention // needed for generating proper C procs sometimes - ); - -const - CallingConvToStr: array [TCallingConvention] of string = ( - '', 'stdcall', 'cdecl', 'safecall', 'syscall', 'inline', 'noinline', - 'fastcall', 'closure', 'noconv'); - -(*[[[cog -def toEnum(name, elems, prefixlen=0): - body = "" - strs = "" - prefix = "" - counter = 0 - for e in elems: - if counter % 4 == 0: prefix = "\n " - else: prefix = "" - body = body + prefix + e + ', ' - strs = strs + prefix + "'%s', " % e[prefixlen:] - counter = counter + 1 - - return ("type\n T%s = (%s);\n T%ss = set of T%s;\n" - % (name, body[:-2], name, name), - "const\n %sToStr: array [T%s] of string = (%s);\n" - % (name, name, strs[:-2])) - -enums = eval(open("data/ast.yml").read()) -for key, val in enums.items(): - (a, b) = toEnum(key, val) - cog.out(a) - cog.out(b) -]]]*) +// +// +// The Nimrod Compiler +// (c) Copyright 2008 Andreas Rumpf +// +// See the file "copying.txt", included in this +// distribution, for details about the copyright. +// +unit ast; + +// abstract syntax tree + symbol table + +interface + +{$include 'config.inc'} + +uses + nsystem, charsets, msgs, nhashes, + nversion, options, strutils, crc, ropes, idents, lists; + +const + ImportTablePos = 0; + ModuleTablePos = 1; + +type + TCallingConvention = ( + ccDefault, // proc has no explicit calling convention + ccStdCall, // procedure is stdcall + ccCDecl, // cdecl + ccSafeCall, // safecall + ccSysCall, // system call + ccInline, // proc should be inlined + ccNoInline, // proc should not be inlined + ccFastCall, // fastcall (pass parameters in registers) + ccClosure, // proc has a closure + ccNoConvention // needed for generating proper C procs sometimes + ); + +const + CallingConvToStr: array [TCallingConvention] of string = ( + '', 'stdcall', 'cdecl', 'safecall', 'syscall', 'inline', 'noinline', + 'fastcall', 'closure', 'noconv'); + +(*[[[cog +def toEnum(name, elems, prefixlen=0): + body = "" + strs = "" + prefix = "" + counter = 0 + for e in elems: + if counter % 4 == 0: prefix = "\n " + else: prefix = "" + body = body + prefix + e + ', ' + strs = strs + prefix + "'%s', " % e[prefixlen:] + counter = counter + 1 + + return ("type\n T%s = (%s);\n T%ss = set of T%s;\n" + % (name, body[:-2], name, name), + "const\n %sToStr: array [T%s] of string = (%s);\n" + % (name, name, strs[:-2])) + +enums = eval(open("data/ast.yml").read()) +for key, val in enums.items(): + (a, b) = toEnum(key, val) + cog.out(a) + cog.out(b) +]]]*) type TNodeKind = ( nkNone, nkEmpty, nkIdent, nkSym, @@ -207,18 +207,18 @@ const 'skVar', 'skProc', 'skIterator', 'skConverter', 'skMacro', 'skTemplate', 'skField', 'skEnumField', 'skForVar', 'skModule', 'skLabel', 'skStub'); -{[[[end]]]} - -type - // symbols that require compiler magic: - TMagic = ( - //[[[cog - //magics = eval(open("data/magic.yml").read()) - //for i in range(0, len(magics)-1): - // cog.out("m" + magics[i] + ", ") - // if (i+1) % 6 == 0: cog.outl("") - //cog.outl("m" + magics[-1]) - //]]] +{[[[end]]]} + +type + // symbols that require compiler magic: + TMagic = ( + //[[[cog + //magics = eval(open("data/magic.yml").read()) + //for i in range(0, len(magics)-1): + // cog.out("m" + magics[i] + ", ") + // if (i+1) % 6 == 0: cog.outl("") + //cog.outl("m" + magics[-1]) + //]]] mNone, mDefined, mLow, mHigh, mSizeOf, mIs, mSucc, mPred, mInc, mDec, mOrd, mNew, mNewFinalize, mNewSeq, mRegisterFinalizer, mLengthOpenArray, mLengthStr, mLengthArray, @@ -257,227 +257,227 @@ type mNStrVal, mNSetIntVal, mNSetFloatVal, mNSetSymbol, mNSetIdent, mNSetType, mNSetStrVal, mNNewNimNode, mNCopyNimNode, mNCopyNimTree, mStrToIdent, mIdentToStr, mEqIdent, mNHint, mNWarning, mNError - //[[[end]]] - ); - -type - PNode = ^TNode; - PNodePtr = ^{@ptr}PNode; - TNodeSeq = array of PNode; - - PType = ^TType; - PSym = ^TSym; - - TNode = {@ignore} record - typ: PType; - strVal: string; - comment: string; - sons: TNodeSeq; // else! - info: TLineInfo; - flags: TNodeFlags; - case Kind: TNodeKind of - nkCharLit, nkIntLit, nkInt8Lit, nkInt16Lit, nkInt32Lit, nkInt64Lit: - (intVal: biggestInt); - nkFloatLit, nkFloat32Lit, nkFloat64Lit: - (floatVal: biggestFloat); - nkSym: (sym: PSym); - nkIdent: (ident: PIdent); - nkMetaNode: (nodePtr: PNodePtr); - end; - {@emit - record // on a 32bit machine, this takes 32 bytes - typ: PType; - comment: string; - info: TLineInfo; - flags: TNodeFlags; - case Kind: TNodeKind of - nkCharLit..nkInt64Lit: - (intVal: biggestInt); - nkFloatLit..nkFloat64Lit: - (floatVal: biggestFloat); - nkStrLit..nkTripleStrLit: - (strVal: string); - nkSym: (sym: PSym); - nkIdent: (ident: PIdent); - nkMetaNode: (nodePtr: PNodePtr); - else (sons: TNodeSeq); - end acyclic; } - - TSymSeq = array of PSym; - TStrTable = object // a table[PIdent] of PSym - counter: int; - data: TSymSeq; - end; - -// -------------- backend information ------------------------------- - - TLocKind = ( - locNone, // no location - locTemp, // temporary location - locLocalVar, // location is a local variable - locGlobalVar, // location is a global variable - locParam, // location is a parameter - locField, // location is a record field - locArrayElem, // location is an array element - locExpr, // "location" is really an expression - locProc, // location is a proc (an address of a procedure) - locData, // location is a constant - locCall, // location is a call expression - locOther // location is something other - ); - - TLocFlag = ( - lfIndirect, // backend introduced a pointer - lfParamCopy, // backend introduced a parameter copy (LLVM) - lfNoDeepCopy, // no need for a deep copy - lfNoDecl, // do not declare it in C - lfDynamicLib, // link symbol to dynamic library - lfHeader // include header file for symbol - ); - - TStorageLoc = ( - OnUnknown, // location is unknown (stack, heap or static) - OnStack, // location is on hardware stack - OnHeap // location is on heap or global (reference counting needed) - ); - - TLocFlags = set of TLocFlag; - TLoc = record - k: TLocKind; // kind of location - s: TStorageLoc; - flags: TLocFlags; // location's flags - t: PType; // type of location - r: PRope; // rope value of location (code generators) - a: int; // location's "address", i.e. slot for temporaries - end; - -// ---------------- end of backend information ------------------------------ - TLibKind = (libHeader, libDynamic); - TLib = object(lists.TListEntry) // also misused for headers! - kind: TLibKind; - generated: bool; - // needed for the backends: - name: PRope; - path: string; - end; - PLib = ^TLib; - - TSym = object(TIdObj) // symbols are identical iff they have the same - // id! - kind: TSymKind; - magic: TMagic; - typ: PType; - name: PIdent; - info: TLineInfo; - owner: PSym; - flags: TSymFlags; - tab: TStrTable; // interface table for modules - ast: PNode; // syntax tree of proc, iterator, etc.: - // the whole proc including header; this is used - // for easy generation of proper error messages - // for variant record fields the discriminant - // expression - options: TOptions; - position: int; // used for many different things: - // for enum fields its position; - // for fields its offset - // for parameters its position - // for a conditional: - // 1 iff the symbol is defined, else 0 - // (or not in symbol table) - offset: int; // offset of record field - loc: TLoc; - annex: PLib; // additional fields (seldom used, so we use a - // reference to another object to safe space) - end; - - TTypeSeq = array of PType; - TType = object(TIdObj) // types are identical iff they have the - // same id; there may be multiple copies of a type - // in memory! - kind: TTypeKind; // kind of type - sons: TTypeSeq; // base types, etc. - n: PNode; // node for types: - // for range types a nkRange node - // for record types a nkRecord node - // for enum types a list of symbols - // else: unused - flags: TTypeFlags; // flags of the type - callConv: TCallingConvention; // for procs - owner: PSym; // the 'owner' of the type - sym: PSym; // types have the sym associated with them - // it is used for converting types to strings - size: BiggestInt; // the size of the type in bytes - // -1 means that the size is unkwown - align: int; // the type's alignment requirements - containerID: int; // used for type checking of generics - loc: TLoc; - end; - - // these are not part of the syntax tree, but nevertherless inherit from TNode - TPair = record - key, val: PObject; - end; - TPairSeq = array of TPair; - - TTable = record // the same as table[PObject] of PObject - counter: int; - data: TPairSeq; - end; - - TIdPair = record - key: PIdObj; - val: PObject; - end; - TIdPairSeq = array of TIdPair; - - TIdTable = record // the same as table[PIdent] of PObject - counter: int; - data: TIdPairSeq; - end; - - TIdNodePair = record - key: PIdObj; - val: PNode; - end; - TIdNodePairSeq = array of TIdNodePair; - - TIdNodeTable = record // the same as table[PIdObj] of PNode - counter: int; - data: TIdNodePairSeq; - end; - - TNodePair = record - h: THash; // because it is expensive to compute! - key: PNode; - val: int; - end; - TNodePairSeq = array of TNodePair; - - TNodeTable = record // the same as table[PNode] of int; - // nodes are compared by structure! - counter: int; - data: TNodePairSeq; - end; - - TObjectSeq = array of PObject; - - TObjectSet = record - counter: int; - data: TObjectSeq; - end; - -const - OverloadableSyms = {@set}[skProc, skIterator, skConverter]; - -const // "MagicToStr" array: - MagicToStr: array [TMagic] of string = ( - //[[[cog - //for i in range(0, len(magics)-1): - // cog.out("'%s', " % magics[i]) - // if (i+1) % 6 == 0: cog.outl("") - //cog.outl("'%s'" % magics[-1]) - //]]] + //[[[end]]] + ); + +type + PNode = ^TNode; + PNodePtr = ^{@ptr}PNode; + TNodeSeq = array of PNode; + + PType = ^TType; + PSym = ^TSym; + + TNode = {@ignore} record + typ: PType; + strVal: string; + comment: string; + sons: TNodeSeq; // else! + info: TLineInfo; + flags: TNodeFlags; + case Kind: TNodeKind of + nkCharLit, nkIntLit, nkInt8Lit, nkInt16Lit, nkInt32Lit, nkInt64Lit: + (intVal: biggestInt); + nkFloatLit, nkFloat32Lit, nkFloat64Lit: + (floatVal: biggestFloat); + nkSym: (sym: PSym); + nkIdent: (ident: PIdent); + nkMetaNode: (nodePtr: PNodePtr); + end; + {@emit + record // on a 32bit machine, this takes 32 bytes + typ: PType; + comment: string; + info: TLineInfo; + flags: TNodeFlags; + case Kind: TNodeKind of + nkCharLit..nkInt64Lit: + (intVal: biggestInt); + nkFloatLit..nkFloat64Lit: + (floatVal: biggestFloat); + nkStrLit..nkTripleStrLit: + (strVal: string); + nkSym: (sym: PSym); + nkIdent: (ident: PIdent); + nkMetaNode: (nodePtr: PNodePtr); + else (sons: TNodeSeq); + end acyclic; } + + TSymSeq = array of PSym; + TStrTable = object // a table[PIdent] of PSym + counter: int; + data: TSymSeq; + end; + +// -------------- backend information ------------------------------- + + TLocKind = ( + locNone, // no location + locTemp, // temporary location + locLocalVar, // location is a local variable + locGlobalVar, // location is a global variable + locParam, // location is a parameter + locField, // location is a record field + locArrayElem, // location is an array element + locExpr, // "location" is really an expression + locProc, // location is a proc (an address of a procedure) + locData, // location is a constant + locCall, // location is a call expression + locOther // location is something other + ); + + TLocFlag = ( + lfIndirect, // backend introduced a pointer + lfParamCopy, // backend introduced a parameter copy (LLVM) + lfNoDeepCopy, // no need for a deep copy + lfNoDecl, // do not declare it in C + lfDynamicLib, // link symbol to dynamic library + lfHeader // include header file for symbol + ); + + TStorageLoc = ( + OnUnknown, // location is unknown (stack, heap or static) + OnStack, // location is on hardware stack + OnHeap // location is on heap or global (reference counting needed) + ); + + TLocFlags = set of TLocFlag; + TLoc = record + k: TLocKind; // kind of location + s: TStorageLoc; + flags: TLocFlags; // location's flags + t: PType; // type of location + r: PRope; // rope value of location (code generators) + a: int; // location's "address", i.e. slot for temporaries + end; + +// ---------------- end of backend information ------------------------------ + TLibKind = (libHeader, libDynamic); + TLib = object(lists.TListEntry) // also misused for headers! + kind: TLibKind; + generated: bool; + // needed for the backends: + name: PRope; + path: string; + end; + PLib = ^TLib; + + TSym = object(TIdObj) // symbols are identical iff they have the same + // id! + kind: TSymKind; + magic: TMagic; + typ: PType; + name: PIdent; + info: TLineInfo; + owner: PSym; + flags: TSymFlags; + tab: TStrTable; // interface table for modules + ast: PNode; // syntax tree of proc, iterator, etc.: + // the whole proc including header; this is used + // for easy generation of proper error messages + // for variant record fields the discriminant + // expression + options: TOptions; + position: int; // used for many different things: + // for enum fields its position; + // for fields its offset + // for parameters its position + // for a conditional: + // 1 iff the symbol is defined, else 0 + // (or not in symbol table) + offset: int; // offset of record field + loc: TLoc; + annex: PLib; // additional fields (seldom used, so we use a + // reference to another object to safe space) + end; + + TTypeSeq = array of PType; + TType = object(TIdObj) // types are identical iff they have the + // same id; there may be multiple copies of a type + // in memory! + kind: TTypeKind; // kind of type + sons: TTypeSeq; // base types, etc. + n: PNode; // node for types: + // for range types a nkRange node + // for record types a nkRecord node + // for enum types a list of symbols + // else: unused + flags: TTypeFlags; // flags of the type + callConv: TCallingConvention; // for procs + owner: PSym; // the 'owner' of the type + sym: PSym; // types have the sym associated with them + // it is used for converting types to strings + size: BiggestInt; // the size of the type in bytes + // -1 means that the size is unkwown + align: int; // the type's alignment requirements + containerID: int; // used for type checking of generics + loc: TLoc; + end; + + // these are not part of the syntax tree, but nevertherless inherit from TNode + TPair = record + key, val: PObject; + end; + TPairSeq = array of TPair; + + TTable = record // the same as table[PObject] of PObject + counter: int; + data: TPairSeq; + end; + + TIdPair = record + key: PIdObj; + val: PObject; + end; + TIdPairSeq = array of TIdPair; + + TIdTable = record // the same as table[PIdent] of PObject + counter: int; + data: TIdPairSeq; + end; + + TIdNodePair = record + key: PIdObj; + val: PNode; + end; + TIdNodePairSeq = array of TIdNodePair; + + TIdNodeTable = record // the same as table[PIdObj] of PNode + counter: int; + data: TIdNodePairSeq; + end; + + TNodePair = record + h: THash; // because it is expensive to compute! + key: PNode; + val: int; + end; + TNodePairSeq = array of TNodePair; + + TNodeTable = record // the same as table[PNode] of int; + // nodes are compared by structure! + counter: int; + data: TNodePairSeq; + end; + + TObjectSeq = array of PObject; + + TObjectSet = record + counter: int; + data: TObjectSeq; + end; + +const + OverloadableSyms = {@set}[skProc, skIterator, skConverter]; + +const // "MagicToStr" array: + MagicToStr: array [TMagic] of string = ( + //[[[cog + //for i in range(0, len(magics)-1): + // cog.out("'%s', " % magics[i]) + // if (i+1) % 6 == 0: cog.outl("") + //cog.outl("'%s'" % magics[-1]) + //]]] 'None', 'Defined', 'Low', 'High', 'SizeOf', 'Is', 'Succ', 'Pred', 'Inc', 'Dec', 'Ord', 'New', 'NewFinalize', 'NewSeq', 'RegisterFinalizer', 'LengthOpenArray', 'LengthStr', 'LengthArray', @@ -516,892 +516,892 @@ const // "MagicToStr" array: 'NStrVal', 'NSetIntVal', 'NSetFloatVal', 'NSetSymbol', 'NSetIdent', 'NSetType', 'NSetStrVal', 'NNewNimNode', 'NCopyNimNode', 'NCopyNimTree', 'StrToIdent', 'IdentToStr', 'EqIdent', 'NHint', 'NWarning', 'NError' - //[[[end]]] - ); - -const - GenericTypes: TTypeKinds = {@set}[tyGeneric, tyGenericParam]; - - StructuralEquivTypes: TTypeKinds = {@set}[ - tyArrayConstr, tyNil, tyTuple, - tyArray, - tySet, - tyRange, - tyPtr, tyRef, - tyVar, - tySequence, - tyProc, tyOpenArray - ]; - - ConcreteTypes: TTypeKinds = {@set}[ - // types of the expr that may occur in:: - // var x = expr - tyBool, tyChar, tyEnum, tyArray, tyObject, tySet, tyTuple, - tyRange, tyPtr, tyRef, tyVar, tySequence, tyProc, - tyPointer, tyOpenArray, - tyString, tyCString, - tyInt..tyInt64, - tyFloat..tyFloat128 - ]; - ConstantDataTypes: TTypeKinds = {@set}[tyArray, tySet, tyTuple]; - ExportableSymKinds = {@set}[skVar, skConst, skProc, skType, - skIterator, skMacro, skTemplate, skConverter, - skStub]; - PersistentNodeFlags: TNodeFlags = {@set}[ - nfBase2, nfBase8, nfBase16, nfAllConst]; - namePos = 0; - genericParamsPos = 1; - paramsPos = 2; - pragmasPos = 3; - codePos = 4; - resultPos = 5; - -var - gId: int; - -function getID: int; -procedure setID(id: int); -procedure IDsynchronizationPoint(idRange: int); - -// creator procs: -function NewSym(symKind: TSymKind; Name: PIdent; owner: PSym): PSym; - -function NewType(kind: TTypeKind; owner: PSym): PType; overload; - -function newNode(kind: TNodeKind): PNode; -function newIntNode(kind: TNodeKind; const intVal: BiggestInt): PNode; -function newIntTypeNode(kind: TNodeKind; const intVal: BiggestInt; - typ: PType): PNode; -function newFloatNode(kind: TNodeKind; const floatVal: BiggestFloat): PNode; -function newStrNode(kind: TNodeKind; const strVal: string): PNode; -function newIdentNode(ident: PIdent; const info: TLineInfo): PNode; -function newSymNode(sym: PSym): PNode; -function newNodeI(kind: TNodeKind; const info: TLineInfo): PNode; -function newNodeIT(kind: TNodeKind; const info: TLineInfo; typ: PType): PNode; - -procedure initStrTable(out x: TStrTable); -procedure initTable(out x: TTable); -procedure initIdTable(out x: TIdTable); -procedure initObjectSet(out x: TObjectSet); -procedure initIdNodeTable(out x: TIdNodeTable); -procedure initNodeTable(out x: TNodeTable); - -// copy procs: -function copyType(t: PType; owner: PSym; keepId: bool): PType; -function copySym(s: PSym; keepId: bool = false): PSym; -procedure assignType(dest, src: PType); - -procedure copyStrTable(out dest: TStrTable; const src: TStrTable); -procedure copyTable(out dest: TTable; const src: TTable); -procedure copyObjectSet(out dest: TObjectSet; const src: TObjectSet); -procedure copyIdTable(var dest: TIdTable; const src: TIdTable); - -function sonsLen(n: PNode): int; overload; -function sonsLen(n: PType): int; overload; - -function lastSon(n: PNode): PNode; overload; -function lastSon(n: PType): PType; overload; -procedure newSons(father: PNode; len: int); overload; -procedure newSons(father: PType; len: int); overload; - -procedure addSon(father, son: PNode); overload; -procedure addSon(father, son: PType); overload; - -procedure addSonIfNotNil(father, n: PNode); -procedure delSon(father: PNode; idx: int); -function hasSonWith(n: PNode; kind: TNodeKind): boolean; -function hasSubnodeWith(n: PNode; kind: TNodeKind): boolean; -procedure replaceSons(n: PNode; oldKind, newKind: TNodeKind); -function sonsNotNil(n: PNode): bool; // for assertions - -function copyNode(src: PNode): PNode; -// does not copy its sons! - -function copyTree(src: PNode): PNode; -// does copy its sons! - -procedure discardSons(father: PNode); - -const // for all kind of hash tables: - GrowthFactor = 2; // must be power of 2, > 0 - StartSize = 8; // must be power of 2, > 0 - -function SameValue(a, b: PNode): Boolean; // a, b are literals -function leValue(a, b: PNode): Boolean; // a <= b? a, b are literals - -function ValueToString(a: PNode): string; - -// ------------- efficient integer sets ------------------------------------- -{@ignore} -type - TBitScalar = int32; // FPC produces wrong code for ``int`` -{@emit -type - TBitScalar = int; } - -const - InitIntSetSize = 8; // must be a power of two! - TrunkShift = 9; - BitsPerTrunk = 1 shl TrunkShift; - // needs to be a power of 2 and divisible by 64 - TrunkMask = BitsPerTrunk-1; - IntsPerTrunk = BitsPerTrunk div (sizeof(TBitScalar)*8); - IntShift = 5+ord(sizeof(TBitScalar)=8); // 5 or 6, depending on int width - IntMask = 1 shl IntShift -1; - -type - PTrunk = ^TTrunk; - TTrunk = record - next: PTrunk; // all nodes are connected with this pointer - key: int; // start address at bit 0 - bits: array [0..IntsPerTrunk-1] of TBitScalar; // a bit vector - end; - TTrunkSeq = array of PTrunk; - TIntSet = record - counter, max: int; - head: PTrunk; - data: TTrunkSeq; - end; - -function IntSetContains(const s: TIntSet; key: int): bool; -procedure IntSetIncl(var s: TIntSet; key: int); -procedure IntSetInit(var s: TIntSet); - -function IntSetContainsOrIncl(var s: TIntSet; key: int): bool; - - -const - debugIds = false; - -procedure registerID(id: PIdObj); - -implementation - -var - usedIds: TIntSet; - -procedure registerID(id: PIdObj); -begin - if debugIDs then - if (id.id = -1) or IntSetContainsOrIncl(usedIds, id.id) then - InternalError('ID already used: ' + toString(id.id)); -end; - -function getID: int; -begin - result := gId; - inc(gId) -end; - -procedure setId(id: int); -begin - gId := max(gId, id+1); -end; - -procedure IDsynchronizationPoint(idRange: int); -begin - gId := (gId div IdRange +1) * IdRange + 1; -end; - -function leValue(a, b: PNode): Boolean; // a <= b? -begin - result := false; - case a.kind of - nkCharLit..nkInt64Lit: - if b.kind in [nkCharLit..nkInt64Lit] then - result := a.intVal <= b.intVal; - nkFloatLit..nkFloat64Lit: - if b.kind in [nkFloatLit..nkFloat64Lit] then - result := a.floatVal <= b.floatVal; - nkStrLit..nkTripleStrLit: begin - if b.kind in [nkStrLit..nkTripleStrLit] then - result := a.strVal <= b.strVal; - end - else InternalError(a.info, 'leValue'); - end -end; - -function SameValue(a, b: PNode): Boolean; -begin - result := false; - case a.kind of - nkCharLit..nkInt64Lit: - if b.kind in [nkCharLit..nkInt64Lit] then - result := a.intVal = b.intVal; - nkFloatLit..nkFloat64Lit: - if b.kind in [nkFloatLit..nkFloat64Lit] then - result := a.floatVal = b.floatVal; - nkStrLit..nkTripleStrLit: begin - if b.kind in [nkStrLit..nkTripleStrLit] then - result := a.strVal = b.strVal; - end - else InternalError(a.info, 'SameValue'); - end -end; - -function ValueToString(a: PNode): string; -begin - case a.kind of - nkCharLit..nkInt64Lit: - result := ToString(a.intVal); - nkFloatLit, nkFloat32Lit, nkFloat64Lit: - result := toStringF(a.floatVal); - nkStrLit..nkTripleStrLit: - result := a.strVal; - else begin - InternalError(a.info, 'valueToString'); - result := '' - end - end -end; - -procedure copyStrTable(out dest: TStrTable; const src: TStrTable); -var - i: int; -begin - dest.counter := src.counter; -{@emit - if isNil(src.data) then exit; -} - setLength(dest.data, length(src.data)); - for i := 0 to high(src.data) do - dest.data[i] := src.data[i]; -end; - -procedure copyIdTable(var dest: TIdTable; const src: TIdTable); -var - i: int; -begin - dest.counter := src.counter; -{@emit - if isNil(src.data) then exit; -} -{@ignore} - setLength(dest.data, length(src.data)); -{@emit - newSeq(dest.data, length(src.data)); } - for i := 0 to high(src.data) do - dest.data[i] := src.data[i]; -end; - -procedure copyTable(out dest: TTable; const src: TTable); -var - i: int; -begin - dest.counter := src.counter; -{@emit - if isNil(src.data) then exit; -} - setLength(dest.data, length(src.data)); - for i := 0 to high(src.data) do - dest.data[i] := src.data[i]; -end; - -procedure copyObjectSet(out dest: TObjectSet; const src: TObjectSet); -var - i: int; -begin - dest.counter := src.counter; -{@emit - if isNil(src.data) then exit; -} - setLength(dest.data, length(src.data)); - for i := 0 to high(src.data) do - dest.data[i] := src.data[i]; -end; - -procedure discardSons(father: PNode); -begin - father.sons := nil; -end; - -function newNode(kind: TNodeKind): PNode; -begin - new(result); -{@ignore} - FillChar(result^, sizeof(result^), 0); -{@emit} - result.kind := kind; - //result.info := UnknownLineInfo(); inlined: - result.info.fileIndex := int32(-1); - result.info.col := int16(-1); - result.info.line := int16(-1); -end; - -function newIntNode(kind: TNodeKind; const intVal: BiggestInt): PNode; -begin - result := newNode(kind); - result.intVal := intVal -end; - -function newIntTypeNode(kind: TNodeKind; const intVal: BiggestInt; - typ: PType): PNode; -begin - result := newIntNode(kind, intVal); - result.typ := typ; -end; - -function newFloatNode(kind: TNodeKind; const floatVal: BiggestFloat): PNode; -begin - result := newNode(kind); - result.floatVal := floatVal -end; - -function newStrNode(kind: TNodeKind; const strVal: string): PNode; -begin - result := newNode(kind); - result.strVal := strVal -end; - -function newIdentNode(ident: PIdent; const info: TLineInfo): PNode; -begin - result := newNode(nkIdent); - result.ident := ident; - result.info := info; -end; - -function newSymNode(sym: PSym): PNode; -begin - result := newNode(nkSym); - result.sym := sym; - result.typ := sym.typ; - result.info := sym.info; -end; - -function newNodeI(kind: TNodeKind; const info: TLineInfo): PNode; -begin - result := newNode(kind); - result.info := info; -end; - -function newNodeIT(kind: TNodeKind; const info: TLineInfo; typ: PType): PNode; -begin - result := newNode(kind); - result.info := info; - result.typ := typ; -end; - -function NewType(kind: TTypeKind; owner: PSym): PType; overload; -begin - new(result); -{@ignore} - FillChar(result^, sizeof(result^), 0); -{@emit} - result.kind := kind; - result.owner := owner; - result.size := -1; - result.align := 2; // default alignment - result.id := getID(); - if debugIds then RegisterId(result); - //if result.id < 2000 then - // MessageOut(typeKindToStr[kind] +{&} ' has id: ' +{&} toString(result.id)); -end; - -procedure assignType(dest, src: PType); -var - i: int; -begin - dest.kind := src.kind; - dest.flags := src.flags; - dest.callConv := src.callConv; - dest.n := src.n; - dest.size := src.size; - dest.align := src.align; - dest.containerID := src.containerID; - newSons(dest, sonsLen(src)); - for i := 0 to sonsLen(src)-1 do - dest.sons[i] := src.sons[i]; -end; - -function copyType(t: PType; owner: PSym; keepId: bool): PType; -begin - result := newType(t.Kind, owner); - assignType(result, t); - if keepId then result.id := t.id - else begin - result.id := getID(); - if debugIds then RegisterId(result); - end; - result.sym := t.sym; - // backend-info should not be copied -end; - -function copySym(s: PSym; keepId: bool = false): PSym; -begin - result := newSym(s.kind, s.name, s.owner); - result.ast := nil; // BUGFIX; was: s.ast which made problems - result.info := s.info; - result.typ := s.typ; - if keepId then result.id := s.id - else begin - result.id := getID(); - if debugIds then RegisterId(result); - end; - result.flags := s.flags; - result.magic := s.magic; - copyStrTable(result.tab, s.tab); - result.options := s.options; - result.position := s.position; - result.loc := s.loc; - result.annex := s.annex; // BUGFIX -end; - -function NewSym(symKind: TSymKind; Name: PIdent; owner: PSym): PSym; -// generates a symbol and initializes the hash field too -begin - new(result); -{@ignore} - FillChar(result^, sizeof(result^), 0); -{@emit} - result.Name := Name; - result.Kind := symKind; - result.flags := {@set}[]; - result.info := UnknownLineInfo(); - result.options := gOptions; - result.owner := owner; - result.offset := -1; - result.id := getID(); - if debugIds then RegisterId(result); - //if result.id < 2000 then - // MessageOut(name.s +{&} ' has id: ' +{&} toString(result.id)); -end; - -procedure initStrTable(out x: TStrTable); -begin - x.counter := 0; -{@emit - newSeq(x.data, startSize); } -{@ignore} - setLength(x.data, startSize); - fillChar(x.data[0], length(x.data)*sizeof(x.data[0]), 0); -{@emit} -end; - -procedure initTable(out x: TTable); -begin - x.counter := 0; -{@emit - newSeq(x.data, startSize); } -{@ignore} - setLength(x.data, startSize); - fillChar(x.data[0], length(x.data)*sizeof(x.data[0]), 0); -{@emit} -end; - -procedure initIdTable(out x: TIdTable); -begin - x.counter := 0; -{@emit - newSeq(x.data, startSize); } -{@ignore} - setLength(x.data, startSize); - fillChar(x.data[0], length(x.data)*sizeof(x.data[0]), 0); -{@emit} -end; - -procedure initObjectSet(out x: TObjectSet); -begin - x.counter := 0; -{@emit - newSeq(x.data, startSize); } -{@ignore} - setLength(x.data, startSize); - fillChar(x.data[0], length(x.data)*sizeof(x.data[0]), 0); -{@emit} -end; - -procedure initIdNodeTable(out x: TIdNodeTable); -begin - x.counter := 0; -{@emit - newSeq(x.data, startSize); } -{@ignore} - setLength(x.data, startSize); - fillChar(x.data[0], length(x.data)*sizeof(x.data[0]), 0); -{@emit} -end; - -procedure initNodeTable(out x: TNodeTable); -begin - x.counter := 0; -{@emit - newSeq(x.data, startSize); } -{@ignore} - setLength(x.data, startSize); - fillChar(x.data[0], length(x.data)*sizeof(x.data[0]), 0); -{@emit} -end; - -function sonsLen(n: PType): int; -begin -{@ignore} - result := length(n.sons); -{@emit - if isNil(n.sons) then result := 0 - else result := length(n.sons); } -end; - -procedure newSons(father: PType; len: int); -var - i, L: int; -begin -{@emit - if isNil(father.sons) then father.sons := @[]; } - L := length(father.sons); - setLength(father.sons, L + len); -{@ignore} - for i := L to L+len-1 do father.sons[i] := nil // needed for FPC -{@emit} -end; - -procedure addSon(father, son: PType); -var - L: int; -begin -{@ignore} - L := length(father.sons); - setLength(father.sons, L+1); - father.sons[L] := son; -{@emit - if isNil(father.sons) then father.sons := @[]; } -{@emit add(father.sons, son); } -end; - -function sonsLen(n: PNode): int; -begin -{@ignore} - result := length(n.sons); -{@emit - if isNil(n.sons) then result := 0 - else result := length(n.sons); } -end; - -procedure newSons(father: PNode; len: int); -var - i, L: int; -begin -{@emit - if isNil(father.sons) then father.sons := @[]; } - L := length(father.sons); - setLength(father.sons, L + len); -{@ignore} - for i := L to L+len-1 do father.sons[i] := nil // needed for FPC -{@emit} -end; - -procedure addSon(father, son: PNode); -var - L: int; -begin -{@ignore} - L := length(father.sons); - setLength(father.sons, L+1); - father.sons[L] := son; -{@emit - if isNil(father.sons) then father.sons := @[]; } -{@emit add(father.sons, son); } -end; - -procedure delSon(father: PNode; idx: int); -var - len, i: int; -begin -{@emit - if isNil(father.sons) then exit; } - len := sonsLen(father); - for i := idx to len-2 do - father.sons[i] := father.sons[i+1]; - setLength(father.sons, len-1); -end; - -function copyNode(src: PNode): PNode; -// does not copy its sons! -begin - if src = nil then begin result := nil; exit end; - result := newNode(src.kind); - result.info := src.info; - result.typ := src.typ; - result.flags := src.flags * PersistentNodeFlags; - case src.Kind of - nkCharLit..nkInt64Lit: - result.intVal := src.intVal; - nkFloatLit, nkFloat32Lit, nkFloat64Lit: - result.floatVal := src.floatVal; - nkSym: - result.sym := src.sym; - nkIdent: - result.ident := src.ident; - nkStrLit..nkTripleStrLit: - result.strVal := src.strVal; - nkMetaNode: - result.nodePtr := src.nodePtr; - else begin end; - end; -end; - -function copyTree(src: PNode): PNode; -// copy a whole syntax tree; performs deep copying -var - i: int; -begin - if src = nil then begin result := nil; exit end; - result := newNode(src.kind); - result.info := src.info; - result.typ := src.typ; - result.flags := src.flags * PersistentNodeFlags; - case src.Kind of - nkCharLit..nkInt64Lit: - result.intVal := src.intVal; - nkFloatLit, nkFloat32Lit, nkFloat64Lit: - result.floatVal := src.floatVal; - nkSym: - result.sym := src.sym; - nkIdent: - result.ident := src.ident; - nkStrLit..nkTripleStrLit: - result.strVal := src.strVal; - nkMetaNode: - result.nodePtr := src.nodePtr; - else begin - result.sons := nil; - newSons(result, sonsLen(src)); - for i := 0 to sonsLen(src)-1 do - result.sons[i] := copyTree(src.sons[i]); - end; - end -end; - -function lastSon(n: PNode): PNode; -begin - result := n.sons[sonsLen(n)-1]; -end; - -function lastSon(n: PType): PType; -begin - result := n.sons[sonsLen(n)-1]; -end; - -function hasSonWith(n: PNode; kind: TNodeKind): boolean; -var - i: int; -begin - for i := 0 to sonsLen(n)-1 do begin - if (n.sons[i] <> nil) and (n.sons[i].kind = kind) then begin - result := true; exit - end - end; - result := false -end; - -function hasSubnodeWith(n: PNode; kind: TNodeKind): boolean; -var - i: int; -begin - case n.kind of - nkEmpty..nkNilLit: result := n.kind = kind; - else begin - for i := 0 to sonsLen(n)-1 do begin - if (n.sons[i] <> nil) and (n.sons[i].kind = kind) - or hasSubnodeWith(n.sons[i], kind) then begin - result := true; exit - end - end; - result := false - end - end -end; - -procedure replaceSons(n: PNode; oldKind, newKind: TNodeKind); -var - i: int; -begin - for i := 0 to sonsLen(n)-1 do - if n.sons[i].kind = oldKind then n.sons[i].kind := newKind -end; - -function sonsNotNil(n: PNode): bool; -var - i: int; -begin - for i := 0 to sonsLen(n)-1 do - if n.sons[i] = nil then begin result := false; exit end; - result := true -end; - -procedure addSonIfNotNil(father, n: PNode); -begin - if n <> nil then addSon(father, n) -end; - -// ---------------- efficient integer sets ---------------------------------- -// Same algorithm as the one the GC uses - -function mustRehash(len, counter: int): bool; -begin - assert(len > counter); - result := (len * 2 < counter * 3) or (len-counter < 4); -end; - -function nextTry(h, maxHash: THash): THash; -begin - result := ((5*h) + 1) and maxHash; - // For any initial h in range(maxHash), repeating that maxHash times - // generates each int in range(maxHash) exactly once (see any text on - // random-number generation for proof). -end; - -procedure IntSetInit(var s: TIntSet); -begin -{@ignore} - fillChar(s, sizeof(s), 0); -{@emit} -{@ignore} - setLength(s.data, InitIntSetSize); - fillChar(s.data[0], length(s.data)*sizeof(s.data[0]), 0); -{@emit - newSeq(s.data, InitIntSetSize); } - s.max := InitIntSetSize-1; - s.counter := 0; - s.head := nil -end; - -function IntSetGet(const t: TIntSet; key: int): PTrunk; -var - h: int; -begin - h := key and t.max; - while t.data[h] <> nil do begin - if t.data[h].key = key then begin - result := t.data[h]; exit - end; - h := nextTry(h, t.max) - end; - result := nil -end; - -procedure IntSetRawInsert(const t: TIntSet; var data: TTrunkSeq; desc: PTrunk); -var - h: int; -begin - h := desc.key and t.max; - while data[h] <> nil do begin - assert(data[h] <> desc); - h := nextTry(h, t.max) - end; - assert(data[h] = nil); - data[h] := desc -end; - -procedure IntSetEnlarge(var t: TIntSet); -var - n: TTrunkSeq; - i, oldMax: int; -begin - oldMax := t.max; - t.max := ((t.max+1)*2)-1; -{@ignore} - setLength(n, t.max + 1); - fillChar(n[0], length(n)*sizeof(n[0]), 0); -{@emit - newSeq(n, t.max+1); } - for i := 0 to oldmax do - if t.data[i] <> nil then - IntSetRawInsert(t, n, t.data[i]); -{@ignore} - t.data := n; -{@emit - swap(t.data, n); } -end; - -function IntSetPut(var t: TIntSet; key: int): PTrunk; -var - h: int; -begin - h := key and t.max; - while t.data[h] <> nil do begin - if t.data[h].key = key then begin - result := t.data[h]; exit - end; - h := nextTry(h, t.max) - end; - - if mustRehash(t.max+1, t.counter) then IntSetEnlarge(t); - inc(t.counter); - h := key and t.max; - while t.data[h] <> nil do h := nextTry(h, t.max); - assert(t.data[h] = nil); - new(result); -{@ignore} - fillChar(result^, sizeof(result^), 0); -{@emit} - result.next := t.head; - result.key := key; - t.head := result; - t.data[h] := result; -end; - -// ---------- slightly higher level procs ---------------------------------- - -function IntSetContains(const s: TIntSet; key: int): bool; -var - u: TBitScalar; - t: PTrunk; -begin - t := IntSetGet(s, shru(key, TrunkShift)); - if t <> nil then begin - u := key and TrunkMask; - result := (t.bits[shru(u, IntShift)] and shlu(1, u and IntMask)) <> 0 - end - else - result := false -end; - -procedure IntSetIncl(var s: TIntSet; key: int); -var - u: TBitScalar; - t: PTrunk; -begin - t := IntSetPut(s, shru(key, TrunkShift)); - u := key and TrunkMask; - t.bits[shru(u, IntShift)] := t.bits[shru(u, IntShift)] - or shlu(1, u and IntMask); -end; - -function IntSetContainsOrIncl(var s: TIntSet; key: int): bool; -var - u: TBitScalar; - t: PTrunk; -begin - t := IntSetGet(s, shru(key, TrunkShift)); - if t <> nil then begin - u := key and TrunkMask; - result := (t.bits[shru(u, IntShift)] and shlu(1, u and IntMask)) <> 0; - if not result then - t.bits[shru(u, IntShift)] := t.bits[shru(u, IntShift)] - or shlu(1, u and IntMask); - end - else begin - IntSetIncl(s, key); - result := false - end -end; -(* -procedure IntSetDebug(const s: TIntSet); -var - it: PTrunk; - i, j: int; -begin - it := s.head; - while it <> nil do begin - for i := 0 to high(it.bits) do - for j := 0 to BitsPerInt-1 do begin - if (it.bits[j] and (1 shl j)) <> 0 then - MessageOut('Contains key: ' + toString(it.key + i * BitsPerInt + j)); - end; - it := it.next - end -end;*) - -initialization - if debugIDs then IntSetInit(usedIds); -end. + //[[[end]]] + ); + +const + GenericTypes: TTypeKinds = {@set}[tyGeneric, tyGenericParam]; + + StructuralEquivTypes: TTypeKinds = {@set}[ + tyArrayConstr, tyNil, tyTuple, + tyArray, + tySet, + tyRange, + tyPtr, tyRef, + tyVar, + tySequence, + tyProc, tyOpenArray + ]; + + ConcreteTypes: TTypeKinds = {@set}[ + // types of the expr that may occur in:: + // var x = expr + tyBool, tyChar, tyEnum, tyArray, tyObject, tySet, tyTuple, + tyRange, tyPtr, tyRef, tyVar, tySequence, tyProc, + tyPointer, tyOpenArray, + tyString, tyCString, + tyInt..tyInt64, + tyFloat..tyFloat128 + ]; + ConstantDataTypes: TTypeKinds = {@set}[tyArray, tySet, tyTuple]; + ExportableSymKinds = {@set}[skVar, skConst, skProc, skType, + skIterator, skMacro, skTemplate, skConverter, + skStub]; + PersistentNodeFlags: TNodeFlags = {@set}[ + nfBase2, nfBase8, nfBase16, nfAllConst]; + namePos = 0; + genericParamsPos = 1; + paramsPos = 2; + pragmasPos = 3; + codePos = 4; + resultPos = 5; + +var + gId: int; + +function getID: int; +procedure setID(id: int); +procedure IDsynchronizationPoint(idRange: int); + +// creator procs: +function NewSym(symKind: TSymKind; Name: PIdent; owner: PSym): PSym; + +function NewType(kind: TTypeKind; owner: PSym): PType; overload; + +function newNode(kind: TNodeKind): PNode; +function newIntNode(kind: TNodeKind; const intVal: BiggestInt): PNode; +function newIntTypeNode(kind: TNodeKind; const intVal: BiggestInt; + typ: PType): PNode; +function newFloatNode(kind: TNodeKind; const floatVal: BiggestFloat): PNode; +function newStrNode(kind: TNodeKind; const strVal: string): PNode; +function newIdentNode(ident: PIdent; const info: TLineInfo): PNode; +function newSymNode(sym: PSym): PNode; +function newNodeI(kind: TNodeKind; const info: TLineInfo): PNode; +function newNodeIT(kind: TNodeKind; const info: TLineInfo; typ: PType): PNode; + +procedure initStrTable(out x: TStrTable); +procedure initTable(out x: TTable); +procedure initIdTable(out x: TIdTable); +procedure initObjectSet(out x: TObjectSet); +procedure initIdNodeTable(out x: TIdNodeTable); +procedure initNodeTable(out x: TNodeTable); + +// copy procs: +function copyType(t: PType; owner: PSym; keepId: bool): PType; +function copySym(s: PSym; keepId: bool = false): PSym; +procedure assignType(dest, src: PType); + +procedure copyStrTable(out dest: TStrTable; const src: TStrTable); +procedure copyTable(out dest: TTable; const src: TTable); +procedure copyObjectSet(out dest: TObjectSet; const src: TObjectSet); +procedure copyIdTable(var dest: TIdTable; const src: TIdTable); + +function sonsLen(n: PNode): int; overload; +function sonsLen(n: PType): int; overload; + +function lastSon(n: PNode): PNode; overload; +function lastSon(n: PType): PType; overload; +procedure newSons(father: PNode; len: int); overload; +procedure newSons(father: PType; len: int); overload; + +procedure addSon(father, son: PNode); overload; +procedure addSon(father, son: PType); overload; + +procedure addSonIfNotNil(father, n: PNode); +procedure delSon(father: PNode; idx: int); +function hasSonWith(n: PNode; kind: TNodeKind): boolean; +function hasSubnodeWith(n: PNode; kind: TNodeKind): boolean; +procedure replaceSons(n: PNode; oldKind, newKind: TNodeKind); +function sonsNotNil(n: PNode): bool; // for assertions + +function copyNode(src: PNode): PNode; +// does not copy its sons! + +function copyTree(src: PNode): PNode; +// does copy its sons! + +procedure discardSons(father: PNode); + +const // for all kind of hash tables: + GrowthFactor = 2; // must be power of 2, > 0 + StartSize = 8; // must be power of 2, > 0 + +function SameValue(a, b: PNode): Boolean; // a, b are literals +function leValue(a, b: PNode): Boolean; // a <= b? a, b are literals + +function ValueToString(a: PNode): string; + +// ------------- efficient integer sets ------------------------------------- +{@ignore} +type + TBitScalar = int32; // FPC produces wrong code for ``int`` +{@emit +type + TBitScalar = int; } + +const + InitIntSetSize = 8; // must be a power of two! + TrunkShift = 9; + BitsPerTrunk = 1 shl TrunkShift; + // needs to be a power of 2 and divisible by 64 + TrunkMask = BitsPerTrunk-1; + IntsPerTrunk = BitsPerTrunk div (sizeof(TBitScalar)*8); + IntShift = 5+ord(sizeof(TBitScalar)=8); // 5 or 6, depending on int width + IntMask = 1 shl IntShift -1; + +type + PTrunk = ^TTrunk; + TTrunk = record + next: PTrunk; // all nodes are connected with this pointer + key: int; // start address at bit 0 + bits: array [0..IntsPerTrunk-1] of TBitScalar; // a bit vector + end; + TTrunkSeq = array of PTrunk; + TIntSet = record + counter, max: int; + head: PTrunk; + data: TTrunkSeq; + end; + +function IntSetContains(const s: TIntSet; key: int): bool; +procedure IntSetIncl(var s: TIntSet; key: int); +procedure IntSetInit(var s: TIntSet); + +function IntSetContainsOrIncl(var s: TIntSet; key: int): bool; + + +const + debugIds = false; + +procedure registerID(id: PIdObj); + +implementation + +var + usedIds: TIntSet; + +procedure registerID(id: PIdObj); +begin + if debugIDs then + if (id.id = -1) or IntSetContainsOrIncl(usedIds, id.id) then + InternalError('ID already used: ' + toString(id.id)); +end; + +function getID: int; +begin + result := gId; + inc(gId) +end; + +procedure setId(id: int); +begin + gId := max(gId, id+1); +end; + +procedure IDsynchronizationPoint(idRange: int); +begin + gId := (gId div IdRange +1) * IdRange + 1; +end; + +function leValue(a, b: PNode): Boolean; // a <= b? +begin + result := false; + case a.kind of + nkCharLit..nkInt64Lit: + if b.kind in [nkCharLit..nkInt64Lit] then + result := a.intVal <= b.intVal; + nkFloatLit..nkFloat64Lit: + if b.kind in [nkFloatLit..nkFloat64Lit] then + result := a.floatVal <= b.floatVal; + nkStrLit..nkTripleStrLit: begin + if b.kind in [nkStrLit..nkTripleStrLit] then + result := a.strVal <= b.strVal; + end + else InternalError(a.info, 'leValue'); + end +end; + +function SameValue(a, b: PNode): Boolean; +begin + result := false; + case a.kind of + nkCharLit..nkInt64Lit: + if b.kind in [nkCharLit..nkInt64Lit] then + result := a.intVal = b.intVal; + nkFloatLit..nkFloat64Lit: + if b.kind in [nkFloatLit..nkFloat64Lit] then + result := a.floatVal = b.floatVal; + nkStrLit..nkTripleStrLit: begin + if b.kind in [nkStrLit..nkTripleStrLit] then + result := a.strVal = b.strVal; + end + else InternalError(a.info, 'SameValue'); + end +end; + +function ValueToString(a: PNode): string; +begin + case a.kind of + nkCharLit..nkInt64Lit: + result := ToString(a.intVal); + nkFloatLit, nkFloat32Lit, nkFloat64Lit: + result := toStringF(a.floatVal); + nkStrLit..nkTripleStrLit: + result := a.strVal; + else begin + InternalError(a.info, 'valueToString'); + result := '' + end + end +end; + +procedure copyStrTable(out dest: TStrTable; const src: TStrTable); +var + i: int; +begin + dest.counter := src.counter; +{@emit + if isNil(src.data) then exit; +} + setLength(dest.data, length(src.data)); + for i := 0 to high(src.data) do + dest.data[i] := src.data[i]; +end; + +procedure copyIdTable(var dest: TIdTable; const src: TIdTable); +var + i: int; +begin + dest.counter := src.counter; +{@emit + if isNil(src.data) then exit; +} +{@ignore} + setLength(dest.data, length(src.data)); +{@emit + newSeq(dest.data, length(src.data)); } + for i := 0 to high(src.data) do + dest.data[i] := src.data[i]; +end; + +procedure copyTable(out dest: TTable; const src: TTable); +var + i: int; +begin + dest.counter := src.counter; +{@emit + if isNil(src.data) then exit; +} + setLength(dest.data, length(src.data)); + for i := 0 to high(src.data) do + dest.data[i] := src.data[i]; +end; + +procedure copyObjectSet(out dest: TObjectSet; const src: TObjectSet); +var + i: int; +begin + dest.counter := src.counter; +{@emit + if isNil(src.data) then exit; +} + setLength(dest.data, length(src.data)); + for i := 0 to high(src.data) do + dest.data[i] := src.data[i]; +end; + +procedure discardSons(father: PNode); +begin + father.sons := nil; +end; + +function newNode(kind: TNodeKind): PNode; +begin + new(result); +{@ignore} + FillChar(result^, sizeof(result^), 0); +{@emit} + result.kind := kind; + //result.info := UnknownLineInfo(); inlined: + result.info.fileIndex := int32(-1); + result.info.col := int16(-1); + result.info.line := int16(-1); +end; + +function newIntNode(kind: TNodeKind; const intVal: BiggestInt): PNode; +begin + result := newNode(kind); + result.intVal := intVal +end; + +function newIntTypeNode(kind: TNodeKind; const intVal: BiggestInt; + typ: PType): PNode; +begin + result := newIntNode(kind, intVal); + result.typ := typ; +end; + +function newFloatNode(kind: TNodeKind; const floatVal: BiggestFloat): PNode; +begin + result := newNode(kind); + result.floatVal := floatVal +end; + +function newStrNode(kind: TNodeKind; const strVal: string): PNode; +begin + result := newNode(kind); + result.strVal := strVal +end; + +function newIdentNode(ident: PIdent; const info: TLineInfo): PNode; +begin + result := newNode(nkIdent); + result.ident := ident; + result.info := info; +end; + +function newSymNode(sym: PSym): PNode; +begin + result := newNode(nkSym); + result.sym := sym; + result.typ := sym.typ; + result.info := sym.info; +end; + +function newNodeI(kind: TNodeKind; const info: TLineInfo): PNode; +begin + result := newNode(kind); + result.info := info; +end; + +function newNodeIT(kind: TNodeKind; const info: TLineInfo; typ: PType): PNode; +begin + result := newNode(kind); + result.info := info; + result.typ := typ; +end; + +function NewType(kind: TTypeKind; owner: PSym): PType; overload; +begin + new(result); +{@ignore} + FillChar(result^, sizeof(result^), 0); +{@emit} + result.kind := kind; + result.owner := owner; + result.size := -1; + result.align := 2; // default alignment + result.id := getID(); + if debugIds then RegisterId(result); + //if result.id < 2000 then + // MessageOut(typeKindToStr[kind] +{&} ' has id: ' +{&} toString(result.id)); +end; + +procedure assignType(dest, src: PType); +var + i: int; +begin + dest.kind := src.kind; + dest.flags := src.flags; + dest.callConv := src.callConv; + dest.n := src.n; + dest.size := src.size; + dest.align := src.align; + dest.containerID := src.containerID; + newSons(dest, sonsLen(src)); + for i := 0 to sonsLen(src)-1 do + dest.sons[i] := src.sons[i]; +end; + +function copyType(t: PType; owner: PSym; keepId: bool): PType; +begin + result := newType(t.Kind, owner); + assignType(result, t); + if keepId then result.id := t.id + else begin + result.id := getID(); + if debugIds then RegisterId(result); + end; + result.sym := t.sym; + // backend-info should not be copied +end; + +function copySym(s: PSym; keepId: bool = false): PSym; +begin + result := newSym(s.kind, s.name, s.owner); + result.ast := nil; // BUGFIX; was: s.ast which made problems + result.info := s.info; + result.typ := s.typ; + if keepId then result.id := s.id + else begin + result.id := getID(); + if debugIds then RegisterId(result); + end; + result.flags := s.flags; + result.magic := s.magic; + copyStrTable(result.tab, s.tab); + result.options := s.options; + result.position := s.position; + result.loc := s.loc; + result.annex := s.annex; // BUGFIX +end; + +function NewSym(symKind: TSymKind; Name: PIdent; owner: PSym): PSym; +// generates a symbol and initializes the hash field too +begin + new(result); +{@ignore} + FillChar(result^, sizeof(result^), 0); +{@emit} + result.Name := Name; + result.Kind := symKind; + result.flags := {@set}[]; + result.info := UnknownLineInfo(); + result.options := gOptions; + result.owner := owner; + result.offset := -1; + result.id := getID(); + if debugIds then RegisterId(result); + //if result.id < 2000 then + // MessageOut(name.s +{&} ' has id: ' +{&} toString(result.id)); +end; + +procedure initStrTable(out x: TStrTable); +begin + x.counter := 0; +{@emit + newSeq(x.data, startSize); } +{@ignore} + setLength(x.data, startSize); + fillChar(x.data[0], length(x.data)*sizeof(x.data[0]), 0); +{@emit} +end; + +procedure initTable(out x: TTable); +begin + x.counter := 0; +{@emit + newSeq(x.data, startSize); } +{@ignore} + setLength(x.data, startSize); + fillChar(x.data[0], length(x.data)*sizeof(x.data[0]), 0); +{@emit} +end; + +procedure initIdTable(out x: TIdTable); +begin + x.counter := 0; +{@emit + newSeq(x.data, startSize); } +{@ignore} + setLength(x.data, startSize); + fillChar(x.data[0], length(x.data)*sizeof(x.data[0]), 0); +{@emit} +end; + +procedure initObjectSet(out x: TObjectSet); +begin + x.counter := 0; +{@emit + newSeq(x.data, startSize); } +{@ignore} + setLength(x.data, startSize); + fillChar(x.data[0], length(x.data)*sizeof(x.data[0]), 0); +{@emit} +end; + +procedure initIdNodeTable(out x: TIdNodeTable); +begin + x.counter := 0; +{@emit + newSeq(x.data, startSize); } +{@ignore} + setLength(x.data, startSize); + fillChar(x.data[0], length(x.data)*sizeof(x.data[0]), 0); +{@emit} +end; + +procedure initNodeTable(out x: TNodeTable); +begin + x.counter := 0; +{@emit + newSeq(x.data, startSize); } +{@ignore} + setLength(x.data, startSize); + fillChar(x.data[0], length(x.data)*sizeof(x.data[0]), 0); +{@emit} +end; + +function sonsLen(n: PType): int; +begin +{@ignore} + result := length(n.sons); +{@emit + if isNil(n.sons) then result := 0 + else result := length(n.sons); } +end; + +procedure newSons(father: PType; len: int); +var + i, L: int; +begin +{@emit + if isNil(father.sons) then father.sons := @[]; } + L := length(father.sons); + setLength(father.sons, L + len); +{@ignore} + for i := L to L+len-1 do father.sons[i] := nil // needed for FPC +{@emit} +end; + +procedure addSon(father, son: PType); +var + L: int; +begin +{@ignore} + L := length(father.sons); + setLength(father.sons, L+1); + father.sons[L] := son; +{@emit + if isNil(father.sons) then father.sons := @[]; } +{@emit add(father.sons, son); } +end; + +function sonsLen(n: PNode): int; +begin +{@ignore} + result := length(n.sons); +{@emit + if isNil(n.sons) then result := 0 + else result := length(n.sons); } +end; + +procedure newSons(father: PNode; len: int); +var + i, L: int; +begin +{@emit + if isNil(father.sons) then father.sons := @[]; } + L := length(father.sons); + setLength(father.sons, L + len); +{@ignore} + for i := L to L+len-1 do father.sons[i] := nil // needed for FPC +{@emit} +end; + +procedure addSon(father, son: PNode); +var + L: int; +begin +{@ignore} + L := length(father.sons); + setLength(father.sons, L+1); + father.sons[L] := son; +{@emit + if isNil(father.sons) then father.sons := @[]; } +{@emit add(father.sons, son); } +end; + +procedure delSon(father: PNode; idx: int); +var + len, i: int; +begin +{@emit + if isNil(father.sons) then exit; } + len := sonsLen(father); + for i := idx to len-2 do + father.sons[i] := father.sons[i+1]; + setLength(father.sons, len-1); +end; + +function copyNode(src: PNode): PNode; +// does not copy its sons! +begin + if src = nil then begin result := nil; exit end; + result := newNode(src.kind); + result.info := src.info; + result.typ := src.typ; + result.flags := src.flags * PersistentNodeFlags; + case src.Kind of + nkCharLit..nkInt64Lit: + result.intVal := src.intVal; + nkFloatLit, nkFloat32Lit, nkFloat64Lit: + result.floatVal := src.floatVal; + nkSym: + result.sym := src.sym; + nkIdent: + result.ident := src.ident; + nkStrLit..nkTripleStrLit: + result.strVal := src.strVal; + nkMetaNode: + result.nodePtr := src.nodePtr; + else begin end; + end; +end; + +function copyTree(src: PNode): PNode; +// copy a whole syntax tree; performs deep copying +var + i: int; +begin + if src = nil then begin result := nil; exit end; + result := newNode(src.kind); + result.info := src.info; + result.typ := src.typ; + result.flags := src.flags * PersistentNodeFlags; + case src.Kind of + nkCharLit..nkInt64Lit: + result.intVal := src.intVal; + nkFloatLit, nkFloat32Lit, nkFloat64Lit: + result.floatVal := src.floatVal; + nkSym: + result.sym := src.sym; + nkIdent: + result.ident := src.ident; + nkStrLit..nkTripleStrLit: + result.strVal := src.strVal; + nkMetaNode: + result.nodePtr := src.nodePtr; + else begin + result.sons := nil; + newSons(result, sonsLen(src)); + for i := 0 to sonsLen(src)-1 do + result.sons[i] := copyTree(src.sons[i]); + end; + end +end; + +function lastSon(n: PNode): PNode; +begin + result := n.sons[sonsLen(n)-1]; +end; + +function lastSon(n: PType): PType; +begin + result := n.sons[sonsLen(n)-1]; +end; + +function hasSonWith(n: PNode; kind: TNodeKind): boolean; +var + i: int; +begin + for i := 0 to sonsLen(n)-1 do begin + if (n.sons[i] <> nil) and (n.sons[i].kind = kind) then begin + result := true; exit + end + end; + result := false +end; + +function hasSubnodeWith(n: PNode; kind: TNodeKind): boolean; +var + i: int; +begin + case n.kind of + nkEmpty..nkNilLit: result := n.kind = kind; + else begin + for i := 0 to sonsLen(n)-1 do begin + if (n.sons[i] <> nil) and (n.sons[i].kind = kind) + or hasSubnodeWith(n.sons[i], kind) then begin + result := true; exit + end + end; + result := false + end + end +end; + +procedure replaceSons(n: PNode; oldKind, newKind: TNodeKind); +var + i: int; +begin + for i := 0 to sonsLen(n)-1 do + if n.sons[i].kind = oldKind then n.sons[i].kind := newKind +end; + +function sonsNotNil(n: PNode): bool; +var + i: int; +begin + for i := 0 to sonsLen(n)-1 do + if n.sons[i] = nil then begin result := false; exit end; + result := true +end; + +procedure addSonIfNotNil(father, n: PNode); +begin + if n <> nil then addSon(father, n) +end; + +// ---------------- efficient integer sets ---------------------------------- +// Same algorithm as the one the GC uses + +function mustRehash(len, counter: int): bool; +begin + assert(len > counter); + result := (len * 2 < counter * 3) or (len-counter < 4); +end; + +function nextTry(h, maxHash: THash): THash; +begin + result := ((5*h) + 1) and maxHash; + // For any initial h in range(maxHash), repeating that maxHash times + // generates each int in range(maxHash) exactly once (see any text on + // random-number generation for proof). +end; + +procedure IntSetInit(var s: TIntSet); +begin +{@ignore} + fillChar(s, sizeof(s), 0); +{@emit} +{@ignore} + setLength(s.data, InitIntSetSize); + fillChar(s.data[0], length(s.data)*sizeof(s.data[0]), 0); +{@emit + newSeq(s.data, InitIntSetSize); } + s.max := InitIntSetSize-1; + s.counter := 0; + s.head := nil +end; + +function IntSetGet(const t: TIntSet; key: int): PTrunk; +var + h: int; +begin + h := key and t.max; + while t.data[h] <> nil do begin + if t.data[h].key = key then begin + result := t.data[h]; exit + end; + h := nextTry(h, t.max) + end; + result := nil +end; + +procedure IntSetRawInsert(const t: TIntSet; var data: TTrunkSeq; desc: PTrunk); +var + h: int; +begin + h := desc.key and t.max; + while data[h] <> nil do begin + assert(data[h] <> desc); + h := nextTry(h, t.max) + end; + assert(data[h] = nil); + data[h] := desc +end; + +procedure IntSetEnlarge(var t: TIntSet); +var + n: TTrunkSeq; + i, oldMax: int; +begin + oldMax := t.max; + t.max := ((t.max+1)*2)-1; +{@ignore} + setLength(n, t.max + 1); + fillChar(n[0], length(n)*sizeof(n[0]), 0); +{@emit + newSeq(n, t.max+1); } + for i := 0 to oldmax do + if t.data[i] <> nil then + IntSetRawInsert(t, n, t.data[i]); +{@ignore} + t.data := n; +{@emit + swap(t.data, n); } +end; + +function IntSetPut(var t: TIntSet; key: int): PTrunk; +var + h: int; +begin + h := key and t.max; + while t.data[h] <> nil do begin + if t.data[h].key = key then begin + result := t.data[h]; exit + end; + h := nextTry(h, t.max) + end; + + if mustRehash(t.max+1, t.counter) then IntSetEnlarge(t); + inc(t.counter); + h := key and t.max; + while t.data[h] <> nil do h := nextTry(h, t.max); + assert(t.data[h] = nil); + new(result); +{@ignore} + fillChar(result^, sizeof(result^), 0); +{@emit} + result.next := t.head; + result.key := key; + t.head := result; + t.data[h] := result; +end; + +// ---------- slightly higher level procs ---------------------------------- + +function IntSetContains(const s: TIntSet; key: int): bool; +var + u: TBitScalar; + t: PTrunk; +begin + t := IntSetGet(s, shru(key, TrunkShift)); + if t <> nil then begin + u := key and TrunkMask; + result := (t.bits[shru(u, IntShift)] and shlu(1, u and IntMask)) <> 0 + end + else + result := false +end; + +procedure IntSetIncl(var s: TIntSet; key: int); +var + u: TBitScalar; + t: PTrunk; +begin + t := IntSetPut(s, shru(key, TrunkShift)); + u := key and TrunkMask; + t.bits[shru(u, IntShift)] := t.bits[shru(u, IntShift)] + or shlu(1, u and IntMask); +end; + +function IntSetContainsOrIncl(var s: TIntSet; key: int): bool; +var + u: TBitScalar; + t: PTrunk; +begin + t := IntSetGet(s, shru(key, TrunkShift)); + if t <> nil then begin + u := key and TrunkMask; + result := (t.bits[shru(u, IntShift)] and shlu(1, u and IntMask)) <> 0; + if not result then + t.bits[shru(u, IntShift)] := t.bits[shru(u, IntShift)] + or shlu(1, u and IntMask); + end + else begin + IntSetIncl(s, key); + result := false + end +end; +(* +procedure IntSetDebug(const s: TIntSet); +var + it: PTrunk; + i, j: int; +begin + it := s.head; + while it <> nil do begin + for i := 0 to high(it.bits) do + for j := 0 to BitsPerInt-1 do begin + if (it.bits[j] and (1 shl j)) <> 0 then + MessageOut('Contains key: ' + toString(it.key + i * BitsPerInt + j)); + end; + it := it.next + end +end;*) + +initialization + if debugIDs then IntSetInit(usedIds); +end. diff --git a/nim/ccgexprs.pas b/nim/ccgexprs.pas index 0bb7183e4..a7a364a52 100644 --- a/nim/ccgexprs.pas +++ b/nim/ccgexprs.pas @@ -2243,8 +2243,8 @@ begin end end; -// ---------------------- generation of complex constants ----------------- - +// ---------------------- generation of complex constants --------------------- +(* function transformRecordExpr(n: PNode): PNode; var i: int; @@ -2263,10 +2263,20 @@ begin field := lookupInRecord(t.n, field.name); if field = nil then InternalError(n.sons[i].info, 'transformRecordExpr: unknown field'); - if result.sons[field.position] <> nil then - InternalError(n.sons[i].info, 'transformRecordExpr: value twice'); + if result.sons[field.position] <> nil then begin + InternalError(n.sons[i].info, 'transformRecordExpr: value twice: ' + + renderTree(n.sons[i])); + end; result.sons[field.position] := copyTree(n.sons[i].sons[1]); end; +end; *) + +function genNamedConstExpr(p: BProc; n: PNode): PRope; +begin + if n.kind = nkExprColonExpr then + result := genConstExpr(p, n.sons[1]) + else + result := genConstExpr(p, n); end; function genConstSimpleList(p: BProc; n: PNode): PRope; @@ -2276,8 +2286,8 @@ begin len := sonsLen(n); result := toRope('{'+''); for i := 0 to len - 2 do - appf(result, '$1,$n', [genConstExpr(p, n.sons[i])]); - if len > 0 then app(result, genConstExpr(p, n.sons[len-1])); + appf(result, '$1,$n', [genNamedConstExpr(p, n.sons[i])]); + if len > 0 then app(result, genNamedConstExpr(p, n.sons[len-1])); app(result, '}' + tnl) end; @@ -2293,16 +2303,9 @@ begin toBitSet(n, cs); result := genRawSetData(cs, int(getSize(n.typ))) end; - nkBracket: begin + nkBracket, nkPar: begin // XXX: tySequence! result := genConstSimpleList(p, n); - end; - nkPar: begin - if hasSonWith(n, nkExprColonExpr) then - trans := transformRecordExpr(n) - else - trans := n; - result := genConstSimpleList(p, trans); end else begin // result := genLiteral(p, n) diff --git a/nim/ccgstmts.pas b/nim/ccgstmts.pas index f3fcdf518..6cff9dc8d 100644 --- a/nim/ccgstmts.pas +++ b/nim/ccgstmts.pas @@ -277,6 +277,7 @@ var i: int; sym: PSym; r, s: PRope; + a: TLoc; begin genLineDir(p, t); assert(t.kind = nkAsmStmt); @@ -286,13 +287,19 @@ begin nkStrLit..nkTripleStrLit: app(s, t.sons[i].strVal); nkSym: begin sym := t.sons[i].sym; - r := sym.loc.r; - if r = nil then begin // if no name has already been given, - // it doesn't matter much: - r := mangleName(sym); - sym.loc.r := r; // but be consequent! - end; - app(s, r) + if sym.kind = skProc then begin + initLocExpr(p, t.sons[i], a); + app(s, rdLoc(a)); + end + else begin + r := sym.loc.r; + if r = nil then begin // if no name has already been given, + // it doesn't matter much: + r := mangleName(sym); + sym.loc.r := r; // but be consequent! + end; + app(s, r) + end end else InternalError(t.sons[i].info, 'genAsmStmt()') diff --git a/nim/ccgtypes.pas b/nim/ccgtypes.pas index 600065078..28db6e009 100644 --- a/nim/ccgtypes.pas +++ b/nim/ccgtypes.pas @@ -612,11 +612,14 @@ begin IdTablePut(m.typeCache, t, con(result, '*'+'')); if not isImportedType(t) then begin useMagic(m, 'TGenericSeq'); - appf(m.s[cfsSeqTypes], - 'struct $2 {$n' + - ' TGenericSeq Sup;$n' + - ' $1 data[SEQ_DECL_SIZE];$n' + - '};$n', [getTypeDescAux(m, t.sons[0], check), result]); + if skipGeneric(t.sons[0]).kind <> tyEmpty then + appf(m.s[cfsSeqTypes], + 'struct $2 {$n' + + ' TGenericSeq Sup;$n' + + ' $1 data[SEQ_DECL_SIZE];$n' + + '};$n', [getTypeDescAux(m, t.sons[0], check), result]) + else + result := toRope('TGenericSeq') end; app(result, '*'+''); end; @@ -1018,6 +1021,7 @@ begin end; if dataGenerated then exit; case t.kind of + tyEmpty: result := toRope('0'+''); tyPointer, tyProc, tyBool, tyChar, tyCString, tyString, tyInt..tyFloat128, tyVar: genTypeInfoAuxBase(gmti, t, result, toRope('0'+'')); diff --git a/nim/msgs.pas b/nim/msgs.pas index 53e1b3388..d7f0d9f82 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]', - 'processing $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, + 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' + ); //[[[end]]] const diff --git a/nim/semfold.pas b/nim/semfold.pas index fdbad9f4c..261e27fd5 100644 --- a/nim/semfold.pas +++ b/nim/semfold.pas @@ -540,32 +540,35 @@ begin case skipRange(n.typ).kind of tyInt..tyInt64: begin case skipRange(a.typ).kind of - tyFloat..tyFloat64: begin + tyFloat..tyFloat64: result := newIntNodeT(nsystem.toInt(getFloat(a)), n); - exit - end; - tyChar: begin + tyChar: result := newIntNodeT(getOrdValue(a), n); - exit - end; - else begin end + else begin + result := a; + result.typ := n.typ; + end end end; tyFloat..tyFloat64: begin case skipRange(a.typ).kind of - tyInt..tyInt64, tyEnum, tyBool, tyChar: begin + tyInt..tyInt64, tyEnum, tyBool, tyChar: result := newFloatNodeT(toFloat(int(getOrdValue(a))), n); - exit + else begin + result := a; + result.typ := n.typ; end - else begin end end end; - tyOpenArray: exit; - else begin end - end; - result := a; - result.typ := n.typ - end; + tyOpenArray, tyProc: begin end; + else begin + //n.sons[1] := a; + //result := n; + result := a; + result.typ := n.typ; + end + end + end else begin end end diff --git a/nim/sigmatch.pas b/nim/sigmatch.pas index ebcbb2529..5195de26c 100644 --- a/nim/sigmatch.pas +++ b/nim/sigmatch.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. diff --git a/nim/transf.pas b/nim/transf.pas index c4ed5740c..476ee4c33 100644 --- a/nim/transf.pas +++ b/nim/transf.pas @@ -440,7 +440,10 @@ begin addSon(result, n.sons[1]); end else result := n.sons[1]; - end; + end; (* + tyArray, tySeq: begin + if skipGeneric(dest + end; *) tyGenericParam, tyAnyEnum: result := n.sons[1]; // happens sometimes for generated assignments, etc. else begin end @@ -450,8 +453,7 @@ end; function skipPassAsOpenArray(n: PNode): PNode; begin result := n; - while result.kind = nkPassAsOpenArray do - result := result.sons[0] + while result.kind = nkPassAsOpenArray do result := result.sons[0] end; type @@ -855,7 +857,7 @@ begin end end; cnst := getConstExpr(c.module, result); - if cnst <> nil then result := cnst; // do not miss an optimization + if cnst <> nil then result := cnst; // do not miss an optimization end; function processTransf(context: PPassContext; n: PNode): PNode; |