diff options
Diffstat (limited to 'nim')
38 files changed, 791 insertions, 627 deletions
diff --git a/nim/ast.pas b/nim/ast.pas index a57632468..0c3137b2b 100644 --- a/nim/ast.pas +++ b/nim/ast.pas @@ -15,7 +15,7 @@ interface {$include 'config.inc'} uses - nsystem, charsets, msgs, hashes, + nsystem, charsets, msgs, nhashes, nversion, options, strutils, crc, ropes, idents, lists; const @@ -245,18 +245,18 @@ type mSymDiffSet, mConStrStr, mConArrArr, mConArrT, mConTArr, mConTT, mSlice, mAppendStrCh, mAppendStrStr, mAppendSeqElem, mAppendSeqSeq, mInRange, mInSet, mAsgn, mRepr, mExit, mSetLengthStr, mSetLengthSeq, - mAssert, mSwap, mIsNil, mArrToSeq, mArray, mOpenArray, - mRange, mSet, mSeq, mInt, mInt8, mInt16, - mInt32, mInt64, mFloat, mFloat32, mFloat64, mBool, - mChar, mString, mCstring, mPointer, mAnyEnum, mEmptySet, - mIntSetBaseType, mNil, mIsMainModule, mCompileDate, mCompileTime, mNimrodVersion, - mNimrodMajor, mNimrodMinor, mNimrodPatch, mCpuEndian, mHostOS, mHostCPU, - mNaN, mInf, mNegInf, mNLen, mNChild, mNSetChild, - mNAdd, mNAddMultiple, mNDel, mNKind, mNIntVal, mNFloatVal, - mNSymbol, mNIdent, mNGetType, mNStrVal, mNSetIntVal, mNSetFloatVal, - mNSetSymbol, mNSetIdent, mNSetType, mNSetStrVal, mNNewNimNode, mNCopyNimNode, - mNCopyNimTree, mStrToIdent, mIdentToStr, mEqIdent, mNHint, mNWarning, - mNError + mAssert, mSwap, mIsNil, mArrToSeq, mCopyStr, mCopyStrLast, + mNewString, mArray, mOpenArray, mRange, mSet, mSeq, + mInt, mInt8, mInt16, mInt32, mInt64, mFloat, + mFloat32, mFloat64, mBool, mChar, mString, mCstring, + mPointer, mAnyEnum, mEmptySet, mIntSetBaseType, mNil, mIsMainModule, + mCompileDate, mCompileTime, mNimrodVersion, mNimrodMajor, mNimrodMinor, mNimrodPatch, + mCpuEndian, mHostOS, mHostCPU, mNaN, mInf, mNegInf, + mNLen, mNChild, mNSetChild, mNAdd, mNAddMultiple, mNDel, + mNKind, mNIntVal, mNFloatVal, mNSymbol, mNIdent, mNGetType, + mNStrVal, mNSetIntVal, mNSetFloatVal, mNSetSymbol, mNSetIdent, mNSetType, + mNSetStrVal, mNNewNimNode, mNCopyNimNode, mNCopyNimTree, mStrToIdent, mIdentToStr, + mEqIdent, mNHint, mNWarning, mNError //[[[end]]] ); @@ -327,7 +327,7 @@ type ); TLocFlag = ( - lfIndirect, // backend introduced a pointer + 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 @@ -504,18 +504,18 @@ const // "MagicToStr" array: 'SymDiffSet', 'ConStrStr', 'ConArrArr', 'ConArrT', 'ConTArr', 'ConTT', 'Slice', 'AppendStrCh', 'AppendStrStr', 'AppendSeqElem', 'AppendSeqSeq', 'InRange', 'InSet', 'Asgn', 'Repr', 'Exit', 'SetLengthStr', 'SetLengthSeq', - 'Assert', 'Swap', 'IsNil', 'ArrToSeq', 'Array', 'OpenArray', - 'Range', 'Set', 'Seq', 'Int', 'Int8', 'Int16', - 'Int32', 'Int64', 'Float', 'Float32', 'Float64', 'Bool', - 'Char', 'String', 'Cstring', 'Pointer', 'AnyEnum', 'EmptySet', - 'IntSetBaseType', 'Nil', 'IsMainModule', 'CompileDate', 'CompileTime', 'NimrodVersion', - 'NimrodMajor', 'NimrodMinor', 'NimrodPatch', 'CpuEndian', 'HostOS', 'HostCPU', - 'NaN', 'Inf', 'NegInf', 'NLen', 'NChild', 'NSetChild', - 'NAdd', 'NAddMultiple', 'NDel', 'NKind', 'NIntVal', 'NFloatVal', - 'NSymbol', 'NIdent', 'NGetType', 'NStrVal', 'NSetIntVal', 'NSetFloatVal', - 'NSetSymbol', 'NSetIdent', 'NSetType', 'NSetStrVal', 'NNewNimNode', 'NCopyNimNode', - 'NCopyNimTree', 'StrToIdent', 'IdentToStr', 'EqIdent', 'NHint', 'NWarning', - 'NError' + 'Assert', 'Swap', 'IsNil', 'ArrToSeq', 'CopyStr', 'CopyStrLast', + 'NewString', 'Array', 'OpenArray', 'Range', 'Set', 'Seq', + 'Int', 'Int8', 'Int16', 'Int32', 'Int64', 'Float', + 'Float32', 'Float64', 'Bool', 'Char', 'String', 'Cstring', + 'Pointer', 'AnyEnum', 'EmptySet', 'IntSetBaseType', 'Nil', 'IsMainModule', + 'CompileDate', 'CompileTime', 'NimrodVersion', 'NimrodMajor', 'NimrodMinor', 'NimrodPatch', + 'CpuEndian', 'HostOS', 'HostCPU', 'NaN', 'Inf', 'NegInf', + 'NLen', 'NChild', 'NSetChild', 'NAdd', 'NAddMultiple', 'NDel', + 'NKind', 'NIntVal', 'NFloatVal', 'NSymbol', 'NIdent', 'NGetType', + 'NStrVal', 'NSetIntVal', 'NSetFloatVal', 'NSetSymbol', 'NSetIdent', 'NSetType', + 'NSetStrVal', 'NNewNimNode', 'NCopyNimNode', 'NCopyNimTree', 'StrToIdent', 'IdentToStr', + 'EqIdent', 'NHint', 'NWarning', 'NError' //[[[end]]] ); diff --git a/nim/astalgo.pas b/nim/astalgo.pas index f7b6f651d..e5475ddd1 100644 --- a/nim/astalgo.pas +++ b/nim/astalgo.pas @@ -17,7 +17,7 @@ interface {$include 'config.inc'} uses - nsystem, ast, hashes, charsets, strutils, options, msgs, ropes, idents; + nsystem, ast, nhashes, charsets, strutils, options, msgs, ropes, idents; function hashNode(p: PObject): THash; diff --git a/nim/ccgexprs.pas b/nim/ccgexprs.pas index 03de5c4de..bd0c520d2 100644 --- a/nim/ccgexprs.pas +++ b/nim/ccgexprs.pas @@ -1254,15 +1254,9 @@ begin refType := skipVarGenericRange(e.sons[1].typ); InitLocExpr(p, e.sons[1], a); initLoc(b, locExpr, a.t, OnHeap); - - if optBoehmGC in gGlobalOptions then - b.r := ropef('($1) newObj(sizeof($2))', - [getTypeDesc(p.module, reftype), - getTypeDesc(p.module, skipGenericRange(reftype.sons[0]))]) - else - b.r := ropef('($1) newObj($2, sizeof($3))', - [getTypeDesc(p.module, reftype), genTypeInfo(p.module, refType), - getTypeDesc(p.module, skipGenericRange(reftype.sons[0]))]); + b.r := ropef('($1) newObj($2, sizeof($3))', + [getTypeDesc(p.module, reftype), genTypeInfo(p.module, refType), + getTypeDesc(p.module, skipGenericRange(reftype.sons[0]))]); genAssignment(p, a, b, {@set}[]); // set the object type: bt := skipGenericRange(refType.sons[0]); @@ -1279,16 +1273,10 @@ begin InitLocExpr(p, e.sons[1], a); InitLocExpr(p, e.sons[2], b); initLoc(c, locExpr, a.t, OnHeap); - if optBoehmGC in gGlobalOptions then - c.r := ropef('($1) newSeq(sizeof($2), $3)', - [getTypeDesc(p.module, seqtype), - getTypeDesc(p.module, skipGenericRange(seqtype.sons[0])), - rdLoc(b)]) - else - c.r := ropef('($1) newSeq($2, $3)', - [getTypeDesc(p.module, seqtype), - genTypeInfo(p.module, seqType), - rdLoc(b)]); + c.r := ropef('($1) newSeq($2, $3)', + [getTypeDesc(p.module, seqtype), + genTypeInfo(p.module, seqType), + rdLoc(b)]); genAssignment(p, a, c, {@set}[]); end; @@ -1945,6 +1933,7 @@ begin mSetLengthSeq: genSetLengthSeq(p, e, d); mIncl, mExcl, mCard, mLtSet, mLeSet, mEqSet, mMulSet, mPlusSet, mMinusSet, mInSet: genSetOp(p, e, d, op); + mNewString, mCopyStr, mCopyStrLast: genCall(p, e, d); mExit: genCall(p, e, d); mArrToSeq: genArrToSeq(p, e, d); mNLen..mNError: diff --git a/nim/ccgstmts.pas b/nim/ccgstmts.pas index 7588f7e15..f3fcdf518 100644 --- a/nim/ccgstmts.pas +++ b/nim/ccgstmts.pas @@ -878,7 +878,7 @@ var i: int; prc: PSym; begin - assert(t <> nil); + //assert(t <> nil); if inCheckpoint(t.info) then MessageOut(renderTree(t)); case t.kind of @@ -913,7 +913,7 @@ begin nkRaiseStmt: genRaiseStmt(p, t); nkTypeSection: begin // we have to emit the type information for object types here to support - // seperate compilation: + // separate compilation: genTypeSection(p.module, t); end; nkCommentStmt, nkNilLit, nkIteratorDef, nkIncludeStmt, nkImportStmt, diff --git a/nim/ccgutils.pas b/nim/ccgutils.pas index 56eff6c9e..49c1a8cee 100644 --- a/nim/ccgutils.pas +++ b/nim/ccgutils.pas @@ -16,7 +16,7 @@ interface uses charsets, nsystem, - ast, astalgo, ropes, lists, hashes, strutils, types, msgs; + ast, astalgo, ropes, lists, nhashes, strutils, types, msgs; function toCChar(c: Char): string; function makeCString(const s: string): PRope; diff --git a/nim/cgen.pas b/nim/cgen.pas index 5dcb7f50b..df8431a30 100644 --- a/nim/cgen.pas +++ b/nim/cgen.pas @@ -16,7 +16,7 @@ interface {$include 'config.inc'} uses - nsystem, ast, astalgo, strutils, hashes, trees, platform, magicsys, + nsystem, ast, astalgo, strutils, nhashes, trees, platform, magicsys, extccomp, options, nversion, nimsets, msgs, crc, bitsets, idents, lists, types, ccgutils, nos, ntime, ropes, nmath, passes, rodread, wordrecg, rnimsyn, treetab; diff --git a/nim/commands.pas b/nim/commands.pas index 8a4435eb0..fde2d26c7 100644 --- a/nim/commands.pas +++ b/nim/commands.pas @@ -1,61 +1,61 @@ -// -// -// The Nimrod Compiler -// (c) Copyright 2008 Andreas Rumpf -// -// See the file "copying.txt", included in this -// distribution, for details about the copyright. -// - -unit commands; - -// This module handles the parsing of command line arguments. - -interface - -{$include 'config.inc'} - -uses - nsystem, charsets, nos, msgs, options, nversion, condsyms, strutils, extccomp, - platform, lists, wordrecg; - -procedure writeCommandLineUsage; - -type - TCmdLinePass = ( - passCmd1, // first pass over the command line - passCmd2, // second pass over the command line - passPP // preprocessor called ProcessCommand() - ); - -procedure ProcessCommand(const switch: string; pass: TCmdLinePass); -procedure processSwitch(const switch, arg: string; pass: TCmdlinePass; - const info: TLineInfo); - -implementation - -{@ignore} -const -{$ifdef fpc} - compileDate = {$I %date%}; -{$else} - compileDate = '2009-0-0'; -{$endif} -{@emit} - -const - HelpMessage = 'Nimrod Compiler Version $1 (' +{&} - compileDate +{&} ') [$2: $3]' +{&} nl +{&} - 'Copyright (c) 2004-2009 by Andreas Rumpf' +{&} nl; - -const - Usage = '' -//[[[cog -//from string import replace -//def f(x): return "+{&} '" + replace(x, "'", "''")[:-1] + "' +{&} nl" -//for line in open("data/basicopt.txt").readlines(): -// cog.outl(f(line)) -//]]] +// +// +// The Nimrod Compiler +// (c) Copyright 2008 Andreas Rumpf +// +// See the file "copying.txt", included in this +// distribution, for details about the copyright. +// + +unit commands; + +// This module handles the parsing of command line arguments. + +interface + +{$include 'config.inc'} + +uses + nsystem, charsets, nos, msgs, options, nversion, condsyms, strutils, extccomp, + platform, lists, wordrecg; + +procedure writeCommandLineUsage; + +type + TCmdLinePass = ( + passCmd1, // first pass over the command line + passCmd2, // second pass over the command line + passPP // preprocessor called ProcessCommand() + ); + +procedure ProcessCommand(const switch: string; pass: TCmdLinePass); +procedure processSwitch(const switch, arg: string; pass: TCmdlinePass; + const info: TLineInfo); + +implementation + +{@ignore} +const +{$ifdef fpc} + compileDate = {$I %date%}; +{$else} + compileDate = '2009-0-0'; +{$endif} +{@emit} + +const + HelpMessage = 'Nimrod Compiler Version $1 (' +{&} + compileDate +{&} ') [$2: $3]' +{&} nl +{&} + 'Copyright (c) 2004-2009 by Andreas Rumpf' +{&} nl; + +const + Usage = '' +//[[[cog +//from string import replace +//def f(x): return "+{&} '" + replace(x, "'", "''")[:-1] + "' +{&} nl" +//for line in open("data/basicopt.txt").readlines(): +// cog.outl(f(line)) +//]]] +{&} 'Usage::' +{&} nl +{&} ' nimrod command [options] inputfile [arguments]' +{&} nl +{&} 'Command::' +{&} nl @@ -88,14 +88,14 @@ const +{&} ' -r, --run run the compiled program with given arguments' +{&} nl +{&} ' --advanced show advanced command line switches' +{&} nl +{&} ' -h, --help show this help' +{&} nl -//[[[end]]] - ; - - AdvancedUsage = '' -//[[[cog -//for line in open("data/advopt.txt").readlines(): -// cog.outl(f(line)) -//]]] +//[[[end]]] + ; + + AdvancedUsage = '' +//[[[cog +//for line in open("data/advopt.txt").readlines(): +// cog.outl(f(line)) +//]]] +{&} 'Advanced commands::' +{&} nl +{&} ' pas convert a Pascal file to Nimrod syntax' +{&} nl +{&} ' pretty pretty print the inputfile' +{&} nl @@ -125,401 +125,454 @@ const +{&} ' --checkpoints:on|off turn on|off checkpoints; for debugging Nimrod' +{&} nl +{&} ' --skip_cfg do not read the general configuration file' +{&} nl +{&} ' --skip_proj_cfg do not read the project''s configuration file' +{&} nl ++{&} ' --gc:refc|boehm use Nimrod''s native GC|Boehm GC' +{&} nl +{&} ' --index:FILE use FILE to generate a documenation index file' +{&} nl +{&} ' --putenv:key=value set an environment variable' +{&} nl +{&} ' --list_cmd list the commands used to execute external programs' +{&} nl +{&} ' --verbosity:0|1|2|3 set Nimrod''s verbosity level (0 is default)' +{&} nl +{&} ' -v, --version show detailed version information' +{&} nl -//[[[end]]] - ; - -function getCommandLineDesc: string; -begin - result := format(HelpMessage, [VersionAsString, - platform.os[platform.hostOS].name, cpu[platform.hostCPU].name]) +{&} Usage -end; - -var - helpWritten: boolean; // BUGFIX 19 - versionWritten: boolean; - advHelpWritten: boolean; - -procedure HelpOnError(pass: TCmdLinePass); -begin - if (pass = passCmd1) and not helpWritten then begin - // BUGFIX 19 - MessageOut(getCommandLineDesc()); - helpWritten := true - end -end; - -procedure writeAdvancedUsage(pass: TCmdLinePass); -begin - if (pass = passCmd1) and not advHelpWritten then begin - // BUGFIX 19 - MessageOut(format(HelpMessage, [VersionAsString, - platform.os[platform.hostOS].name, - cpu[platform.hostCPU].name]) +{&} - AdvancedUsage); - advHelpWritten := true; - helpWritten := true; - halt(0); - end -end; - -procedure writeVersionInfo(pass: TCmdLinePass); -begin - if (pass = passCmd1) and not versionWritten then begin - versionWritten := true; - helpWritten := true; - messageOut(format(HelpMessage, [VersionAsString, - platform.os[platform.hostOS].name, - cpu[platform.hostCPU].name])) - end -end; - -procedure writeCommandLineUsage; -begin - if not helpWritten then begin - messageOut(getCommandLineDesc()); - helpWritten := true - end -end; - -procedure InvalidCmdLineOption(pass: TCmdLinePass; const switch: string; - const info: TLineInfo); -begin - liMessage(info, errInvalidCmdLineOption, switch) -end; - -procedure splitSwitch(const switch: string; out cmd, arg: string; - pass: TCmdLinePass; const info: TLineInfo); -var - i: int; -begin - cmd := ''; - i := strStart; - if (i < length(switch)+strStart) and (switch[i] = '-') then inc(i); - if (i < length(switch)+strStart) and (switch[i] = '-') then inc(i); - while i < length(switch) + strStart do begin - case switch[i] of - 'a'..'z', 'A'..'Z', '0'..'9', '_', '.': - addChar(cmd, switch[i]); - else break; - end; - inc(i); - end; - if i >= length(switch) + strStart then - arg := '' - else if switch[i] in [':', '=', '['] then - arg := ncopy(switch, i + 1) - else - InvalidCmdLineOption(pass, switch, info) -end; - -procedure ProcessOnOffSwitch(const op: TOptions; const arg: string; - pass: TCmdlinePass; const info: TLineInfo); -begin - case whichKeyword(arg) of - wOn: gOptions := gOptions + op; - wOff: gOptions := gOptions - op; - else liMessage(info, errOnOrOffExpectedButXFound, arg) - end -end; - -procedure ProcessOnOffSwitchG(const op: TGlobalOptions; const arg: string; - pass: TCmdlinePass; const info: TLineInfo); -begin - case whichKeyword(arg) of - wOn: gGlobalOptions := gGlobalOptions + op; - wOff: gGlobalOptions := gGlobalOptions - op; - else liMessage(info, errOnOrOffExpectedButXFound, arg) - end -end; - -procedure ExpectArg(const switch, arg: string; pass: TCmdLinePass; - const info: TLineInfo); -begin - if (arg = '') then - liMessage(info, errCmdLineArgExpected, switch) -end; - -procedure ProcessSpecificNote(const arg: string; state: TSpecialWord; - pass: TCmdlinePass; const info: TLineInfo); -var - i, x: int; - n: TNoteKind; - id: string; -begin - id := ''; - // arg = "X]:on|off" - i := strStart; - n := hintMin; - while (i < length(arg)+strStart) and (arg[i] <> ']') do begin - addChar(id, arg[i]); - inc(i) - end; - if (i < length(arg)+strStart) and (arg[i] = ']') then - inc(i) - else - InvalidCmdLineOption(pass, arg, info); - if (i < length(arg)+strStart) and (arg[i] in [':', '=']) then - inc(i) - else - InvalidCmdLineOption(pass, arg, info); - if state = wHint then begin - x := findStr(msgs.HintsToStr, id); - if x >= 0 then - n := TNoteKind(x + ord(hintMin)) - else - InvalidCmdLineOption(pass, arg, info) - end - else begin - x := findStr(msgs.WarningsToStr, id); - if x >= 0 then - n := TNoteKind(x + ord(warnMin)) - else - InvalidCmdLineOption(pass, arg, info) - end; - case whichKeyword(ncopy(arg, i)) of - wOn: include(gNotes, n); - wOff: exclude(gNotes, n); - else liMessage(info, errOnOrOffExpectedButXFound, arg) - end -end; - -function processPath(const path: string): string; -begin - result := UnixToNativePath(format(path, - ['nimrod', getPrefixDir(), 'lib', libpath])) -end; - -procedure processCompile(const filename: string); -var - found, trunc, ext: string; -begin - found := findFile(filename); - if found = '' then found := filename; - splitFilename(found, trunc, ext); - extccomp.addExternalFileToCompile(trunc); - extccomp.addFileToLink(completeCFilePath(trunc, false)); -end; - -procedure processSwitch(const switch, arg: string; pass: TCmdlinePass; - const info: TLineInfo); -var - theOS: TSystemOS; - cpu: TSystemCPU; - key, val, path: string; -begin - case whichKeyword(switch) of - wPath, wP: begin - expectArg(switch, arg, pass, info); - path := processPath(arg); - {@discard} lists.IncludeStr(options.searchPaths, path) - end; - wOut, wO: begin - expectArg(switch, arg, pass, info); - options.outFile := arg; - end; - wDefine, wD: begin - expectArg(switch, arg, pass, info); - DefineSymbol(arg) - end; - wUndef, wU: begin - expectArg(switch, arg, pass, info); - UndefSymbol(arg) - end; - wCompile: begin - expectArg(switch, arg, pass, info); - if pass in {@set}[passCmd2, passPP] then - processCompile(arg); - end; - wLink: begin - expectArg(switch, arg, pass, info); - if pass in {@set}[passCmd2, passPP] then - addFileToLink(arg); - end; - wDebuginfo: include(gGlobalOptions, optCDebug); - wCompileOnly, wC: include(gGlobalOptions, optCompileOnly); - wNoLinking: include(gGlobalOptions, optNoLinking); - wForceBuild, wF: include(gGlobalOptions, optForceFullMake); - wGC: begin - case whichKeyword(arg) of - wBoehm: begin - include(gGlobalOptions, optBoehmGC); - exclude(gGlobalOptions, optRefcGC); - DefineSymbol('boehmgc'); - end; - wRefc: begin - exclude(gGlobalOptions, optBoehmGC); - include(gGlobalOptions, optRefcGC) - end; - wNone: begin - exclude(gGlobalOptions, optRefcGC); - exclude(gGlobalOptions, optBoehmGC); - defineSymbol('nogc'); - end - else - liMessage(info, errNoneBoehmRefcExpectedButXFound, arg) - end - end; - wWarnings, wW: ProcessOnOffSwitch({@set}[optWarns], arg, pass, info); - wWarning: ProcessSpecificNote(arg, wWarning, pass, info); - wHint: ProcessSpecificNote(arg, wHint, pass, info); - wHints: ProcessOnOffSwitch({@set}[optHints], arg, pass, info); - wCheckpoints: ProcessOnOffSwitch({@set}[optCheckpoints], arg, pass, info); - wStackTrace: ProcessOnOffSwitch({@set}[optStackTrace], arg, pass, info); - wLineTrace: ProcessOnOffSwitch({@set}[optLineTrace], arg, pass, info); - wDebugger: begin - ProcessOnOffSwitch({@set}[optEndb], arg, pass, info); - if optEndb in gOptions then - DefineSymbol('endb') - else - UndefSymbol('endb') - end; - wProfiler: begin - ProcessOnOffSwitch({@set}[optProfiler], arg, pass, info); - if optProfiler in gOptions then DefineSymbol('profiler') - else UndefSymbol('profiler') - end; - wChecks, wX: ProcessOnOffSwitch(checksOptions, arg, pass, info); - wObjChecks: ProcessOnOffSwitch({@set}[optObjCheck], arg, pass, info); - wFieldChecks: ProcessOnOffSwitch({@set}[optFieldCheck], arg, pass, info); - wRangeChecks: ProcessOnOffSwitch({@set}[optRangeCheck], arg, pass, info); - wBoundChecks: ProcessOnOffSwitch({@set}[optBoundsCheck], arg, pass, info); - wOverflowChecks: ProcessOnOffSwitch({@set}[optOverflowCheck], arg, pass, info); - wLineDir: ProcessOnOffSwitch({@set}[optLineDir], arg, pass, info); - wAssertions, wA: ProcessOnOffSwitch({@set}[optAssert], arg, pass, info); - wDeadCodeElim: ProcessOnOffSwitchG({@set}[optDeadCodeElim], arg, pass, info); - wOpt: begin - case whichKeyword(arg) of - wSpeed: begin - include(gOptions, optOptimizeSpeed); - exclude(gOptions, optOptimizeSize) - end; - wSize: begin - exclude(gOptions, optOptimizeSpeed); - include(gOptions, optOptimizeSize) - end; - wNone: begin - exclude(gOptions, optOptimizeSpeed); - exclude(gOptions, optOptimizeSize) - end - else - liMessage(info, errNoneSpeedOrSizeExpectedButXFound, arg) - end - end; - wApp: begin - case whichKeyword(arg) of - wGui: begin - include(gGlobalOptions, optGenGuiApp); - defineSymbol('guiapp') - end; - wConsole: - exclude(gGlobalOptions, optGenGuiApp); - wLib: begin - include(gGlobalOptions, optGenDynLib); - exclude(gGlobalOptions, optGenGuiApp); - defineSymbol('library') - end; - else - liMessage(info, errGuiConsoleOrLibExpectedButXFound, arg) - end - end; - wListDef: begin - if pass in {@set}[passCmd2, passPP] then - condsyms.listSymbols(); - end; - wPassC, wT: begin - expectArg(switch, arg, pass, info); - if pass in {@set}[passCmd2, passPP] then - extccomp.addCompileOption(arg) - end; - wPassL, wL: begin - expectArg(switch, arg, pass, info); - if pass in {@set}[passCmd2, passPP] then - extccomp.addLinkOption(arg) - end; - wIndex: begin - expectArg(switch, arg, pass, info); - if pass in {@set}[passCmd2, passPP] then - gIndexFile := arg - end; - wImport: begin - expectArg(switch, arg, pass, info); - options.addImplicitMod(arg); - end; - wListCmd: include(gGlobalOptions, optListCmd); - wGenMapping: include(gGlobalOptions, optGenMapping); - wOS: begin - if (pass = passCmd1) then begin - theOS := platform.NameToOS(arg); - if theOS = osNone then - liMessage(info, errUnknownOS, arg); - if theOS <> platform.hostOS then begin - setTarget(theOS, targetCPU); - include(gGlobalOptions, optCompileOnly); - condsyms.InitDefines() - end - end - end; - wCPU: begin - if (pass = passCmd1) then begin - cpu := platform.NameToCPU(arg); - if cpu = cpuNone then - liMessage(info, errUnknownCPU, arg); - if cpu <> platform.hostCPU then begin - setTarget(targetOS, cpu); - include(gGlobalOptions, optCompileOnly); - condsyms.InitDefines() - end - end - end; - wRun, wR: include(gGlobalOptions, optRun); - wVerbosity: begin - expectArg(switch, arg, pass, info); - gVerbosity := parseInt(arg); - end; - wVersion, wV: writeVersionInfo(pass); - wAdvanced: writeAdvancedUsage(pass); - wHelp, wH: helpOnError(pass); - wSymbolFiles: ProcessOnOffSwitchG({@set}[optSymbolFiles], arg, pass, info); - wSkipCfg: include(gGlobalOptions, optSkipConfigFile); - wSkipProjCfg: include(gGlobalOptions, optSkipProjConfigFile); - wGenScript: include(gGlobalOptions, optGenScript); - wLib: begin - expectArg(switch, arg, pass, info); - libpath := processPath(arg) - end; - wPutEnv: begin - expectArg(switch, arg, pass, info); - splitSwitch(arg, key, val, pass, info); - nos.putEnv(key, val); - end; - wCC: begin - expectArg(switch, arg, pass, info); - setCC(arg) - end; - wMaxErr: begin - expectArg(switch, arg, pass, info); - gErrorMax := parseInt(arg); - end; - else if strutils.find(switch, '.') >= strStart then - options.setConfigVar(switch, arg) - else - InvalidCmdLineOption(pass, switch, info) - end -end; - -procedure ProcessCommand(const switch: string; pass: TCmdLinePass); -var - cmd, arg: string; - info: TLineInfo; -begin - info := newLineInfo('command line', 1, 1); - splitSwitch(switch, cmd, arg, pass, info); - ProcessSwitch(cmd, arg, pass, info) -end; - -end. +//[[[end]]] + ; + +function getCommandLineDesc: string; +begin + result := format(HelpMessage, [VersionAsString, + platform.os[platform.hostOS].name, cpu[platform.hostCPU].name]) +{&} Usage +end; + +var + helpWritten: boolean; // BUGFIX 19 + versionWritten: boolean; + advHelpWritten: boolean; + +procedure HelpOnError(pass: TCmdLinePass); +begin + if (pass = passCmd1) and not helpWritten then begin + // BUGFIX 19 + MessageOut(getCommandLineDesc()); + helpWritten := true + end +end; + +procedure writeAdvancedUsage(pass: TCmdLinePass); +begin + if (pass = passCmd1) and not advHelpWritten then begin + // BUGFIX 19 + MessageOut(format(HelpMessage, [VersionAsString, + platform.os[platform.hostOS].name, + cpu[platform.hostCPU].name]) +{&} + AdvancedUsage); + advHelpWritten := true; + helpWritten := true; + halt(0); + end +end; + +procedure writeVersionInfo(pass: TCmdLinePass); +begin + if (pass = passCmd1) and not versionWritten then begin + versionWritten := true; + helpWritten := true; + messageOut(format(HelpMessage, [VersionAsString, + platform.os[platform.hostOS].name, + cpu[platform.hostCPU].name])) + end +end; + +procedure writeCommandLineUsage; +begin + if not helpWritten then begin + messageOut(getCommandLineDesc()); + helpWritten := true + end +end; + +procedure InvalidCmdLineOption(pass: TCmdLinePass; const switch: string; + const info: TLineInfo); +begin + liMessage(info, errInvalidCmdLineOption, switch) +end; + +procedure splitSwitch(const switch: string; out cmd, arg: string; + pass: TCmdLinePass; const info: TLineInfo); +var + i: int; +begin + cmd := ''; + i := strStart; + if (i < length(switch)+strStart) and (switch[i] = '-') then inc(i); + if (i < length(switch)+strStart) and (switch[i] = '-') then inc(i); + while i < length(switch) + strStart do begin + case switch[i] of + 'a'..'z', 'A'..'Z', '0'..'9', '_', '.': + addChar(cmd, switch[i]); + else break; + end; + inc(i); + end; + if i >= length(switch) + strStart then + arg := '' + else if switch[i] in [':', '=', '['] then + arg := ncopy(switch, i + 1) + else + InvalidCmdLineOption(pass, switch, info) +end; + +procedure ProcessOnOffSwitch(const op: TOptions; const arg: string; + pass: TCmdlinePass; const info: TLineInfo); +begin + case whichKeyword(arg) of + wOn: gOptions := gOptions + op; + wOff: gOptions := gOptions - op; + else liMessage(info, errOnOrOffExpectedButXFound, arg) + end +end; + +procedure ProcessOnOffSwitchG(const op: TGlobalOptions; const arg: string; + pass: TCmdlinePass; const info: TLineInfo); +begin + case whichKeyword(arg) of + wOn: gGlobalOptions := gGlobalOptions + op; + wOff: gGlobalOptions := gGlobalOptions - op; + else liMessage(info, errOnOrOffExpectedButXFound, arg) + end +end; + +procedure ExpectArg(const switch, arg: string; pass: TCmdLinePass; + const info: TLineInfo); +begin + if (arg = '') then + liMessage(info, errCmdLineArgExpected, switch) +end; + +procedure ExpectNoArg(const switch, arg: string; pass: TCmdLinePass; + const info: TLineInfo); +begin + if (arg <> '') then + liMessage(info, errCmdLineNoArgExpected, switch) +end; + +procedure ProcessSpecificNote(const arg: string; state: TSpecialWord; + pass: TCmdlinePass; const info: TLineInfo); +var + i, x: int; + n: TNoteKind; + id: string; +begin + id := ''; + // arg = "X]:on|off" + i := strStart; + n := hintMin; + while (i < length(arg)+strStart) and (arg[i] <> ']') do begin + addChar(id, arg[i]); + inc(i) + end; + if (i < length(arg)+strStart) and (arg[i] = ']') then + inc(i) + else + InvalidCmdLineOption(pass, arg, info); + if (i < length(arg)+strStart) and (arg[i] in [':', '=']) then + inc(i) + else + InvalidCmdLineOption(pass, arg, info); + if state = wHint then begin + x := findStr(msgs.HintsToStr, id); + if x >= 0 then + n := TNoteKind(x + ord(hintMin)) + else + InvalidCmdLineOption(pass, arg, info) + end + else begin + x := findStr(msgs.WarningsToStr, id); + if x >= 0 then + n := TNoteKind(x + ord(warnMin)) + else + InvalidCmdLineOption(pass, arg, info) + end; + case whichKeyword(ncopy(arg, i)) of + wOn: include(gNotes, n); + wOff: exclude(gNotes, n); + else liMessage(info, errOnOrOffExpectedButXFound, arg) + end +end; + +function processPath(const path: string): string; +begin + result := UnixToNativePath(format(path, + ['nimrod', getPrefixDir(), 'lib', libpath])) +end; + +procedure processCompile(const filename: string); +var + found, trunc, ext: string; +begin + found := findFile(filename); + if found = '' then found := filename; + splitFilename(found, trunc, ext); + extccomp.addExternalFileToCompile(trunc); + extccomp.addFileToLink(completeCFilePath(trunc, false)); +end; + +procedure processSwitch(const switch, arg: string; pass: TCmdlinePass; + const info: TLineInfo); +var + theOS: TSystemOS; + cpu: TSystemCPU; + key, val, path: string; +begin + case whichKeyword(switch) of + wPath, wP: begin + expectArg(switch, arg, pass, info); + path := processPath(arg); + {@discard} lists.IncludeStr(options.searchPaths, path) + end; + wOut, wO: begin + expectArg(switch, arg, pass, info); + options.outFile := arg; + end; + wDefine, wD: begin + expectArg(switch, arg, pass, info); + DefineSymbol(arg) + end; + wUndef, wU: begin + expectArg(switch, arg, pass, info); + UndefSymbol(arg) + end; + wCompile: begin + expectArg(switch, arg, pass, info); + if pass in {@set}[passCmd2, passPP] then + processCompile(arg); + end; + wLink: begin + expectArg(switch, arg, pass, info); + if pass in {@set}[passCmd2, passPP] then + addFileToLink(arg); + end; + wDebuginfo: begin + expectNoArg(switch, arg, pass, info); + include(gGlobalOptions, optCDebug); + end; + wCompileOnly, wC: begin + expectNoArg(switch, arg, pass, info); + include(gGlobalOptions, optCompileOnly); + end; + wNoLinking: begin + expectNoArg(switch, arg, pass, info); + include(gGlobalOptions, optNoLinking); + end; + wForceBuild, wF: begin + expectNoArg(switch, arg, pass, info); + include(gGlobalOptions, optForceFullMake); + end; + wGC: begin + expectArg(switch, arg, pass, info); + case whichKeyword(arg) of + wBoehm: begin + include(gGlobalOptions, optBoehmGC); + exclude(gGlobalOptions, optRefcGC); + DefineSymbol('boehmgc'); + end; + wRefc: begin + exclude(gGlobalOptions, optBoehmGC); + include(gGlobalOptions, optRefcGC) + end; + wNone: begin + exclude(gGlobalOptions, optRefcGC); + exclude(gGlobalOptions, optBoehmGC); + defineSymbol('nogc'); + end + else + liMessage(info, errNoneBoehmRefcExpectedButXFound, arg) + end + end; + wWarnings, wW: ProcessOnOffSwitch({@set}[optWarns], arg, pass, info); + wWarning: ProcessSpecificNote(arg, wWarning, pass, info); + wHint: ProcessSpecificNote(arg, wHint, pass, info); + wHints: ProcessOnOffSwitch({@set}[optHints], arg, pass, info); + wCheckpoints: ProcessOnOffSwitch({@set}[optCheckpoints], arg, pass, info); + wStackTrace: ProcessOnOffSwitch({@set}[optStackTrace], arg, pass, info); + wLineTrace: ProcessOnOffSwitch({@set}[optLineTrace], arg, pass, info); + wDebugger: begin + ProcessOnOffSwitch({@set}[optEndb], arg, pass, info); + if optEndb in gOptions then + DefineSymbol('endb') + else + UndefSymbol('endb') + end; + wProfiler: begin + ProcessOnOffSwitch({@set}[optProfiler], arg, pass, info); + if optProfiler in gOptions then DefineSymbol('profiler') + else UndefSymbol('profiler') + end; + wChecks, wX: ProcessOnOffSwitch(checksOptions, arg, pass, info); + wObjChecks: ProcessOnOffSwitch({@set}[optObjCheck], arg, pass, info); + wFieldChecks: ProcessOnOffSwitch({@set}[optFieldCheck], arg, pass, info); + wRangeChecks: ProcessOnOffSwitch({@set}[optRangeCheck], arg, pass, info); + wBoundChecks: ProcessOnOffSwitch({@set}[optBoundsCheck], arg, pass, info); + wOverflowChecks: ProcessOnOffSwitch({@set}[optOverflowCheck], arg, pass, info); + wLineDir: ProcessOnOffSwitch({@set}[optLineDir], arg, pass, info); + wAssertions, wA: ProcessOnOffSwitch({@set}[optAssert], arg, pass, info); + wDeadCodeElim: ProcessOnOffSwitchG({@set}[optDeadCodeElim], arg, pass, info); + wOpt: begin + expectArg(switch, arg, pass, info); + case whichKeyword(arg) of + wSpeed: begin + include(gOptions, optOptimizeSpeed); + exclude(gOptions, optOptimizeSize) + end; + wSize: begin + exclude(gOptions, optOptimizeSpeed); + include(gOptions, optOptimizeSize) + end; + wNone: begin + exclude(gOptions, optOptimizeSpeed); + exclude(gOptions, optOptimizeSize) + end + else + liMessage(info, errNoneSpeedOrSizeExpectedButXFound, arg) + end + end; + wApp: begin + expectArg(switch, arg, pass, info); + case whichKeyword(arg) of + wGui: begin + include(gGlobalOptions, optGenGuiApp); + defineSymbol('guiapp') + end; + wConsole: + exclude(gGlobalOptions, optGenGuiApp); + wLib: begin + include(gGlobalOptions, optGenDynLib); + exclude(gGlobalOptions, optGenGuiApp); + defineSymbol('library') + end; + else + liMessage(info, errGuiConsoleOrLibExpectedButXFound, arg) + end + end; + wListDef: begin + expectNoArg(switch, arg, pass, info); + if pass in {@set}[passCmd2, passPP] then + condsyms.listSymbols(); + end; + wPassC, wT: begin + expectArg(switch, arg, pass, info); + if pass in {@set}[passCmd2, passPP] then + extccomp.addCompileOption(arg) + end; + wPassL, wL: begin + expectArg(switch, arg, pass, info); + if pass in {@set}[passCmd2, passPP] then + extccomp.addLinkOption(arg) + end; + wIndex: begin + expectArg(switch, arg, pass, info); + if pass in {@set}[passCmd2, passPP] then + gIndexFile := arg + end; + wImport: begin + expectArg(switch, arg, pass, info); + options.addImplicitMod(arg); + end; + wListCmd: begin + expectNoArg(switch, arg, pass, info); + include(gGlobalOptions, optListCmd); + end; + wGenMapping: begin + expectNoArg(switch, arg, pass, info); + include(gGlobalOptions, optGenMapping); + end; + wOS: begin + expectArg(switch, arg, pass, info); + if (pass = passCmd1) then begin + theOS := platform.NameToOS(arg); + if theOS = osNone then + liMessage(info, errUnknownOS, arg); + if theOS <> platform.hostOS then begin + setTarget(theOS, targetCPU); + include(gGlobalOptions, optCompileOnly); + condsyms.InitDefines() + end + end + end; + wCPU: begin + expectArg(switch, arg, pass, info); + if (pass = passCmd1) then begin + cpu := platform.NameToCPU(arg); + if cpu = cpuNone then + liMessage(info, errUnknownCPU, arg); + if cpu <> platform.hostCPU then begin + setTarget(targetOS, cpu); + include(gGlobalOptions, optCompileOnly); + condsyms.InitDefines() + end + end + end; + wRun, wR: begin + expectNoArg(switch, arg, pass, info); + include(gGlobalOptions, optRun); + end; + wVerbosity: begin + expectArg(switch, arg, pass, info); + gVerbosity := parseInt(arg); + end; + wVersion, wV: begin + expectNoArg(switch, arg, pass, info); + writeVersionInfo(pass); + end; + wAdvanced: begin + expectNoArg(switch, arg, pass, info); + writeAdvancedUsage(pass); + end; + wHelp, wH: begin + expectNoArg(switch, arg, pass, info); + helpOnError(pass); + end; + wSymbolFiles: ProcessOnOffSwitchG({@set}[optSymbolFiles], arg, pass, info); + wSkipCfg: begin + expectNoArg(switch, arg, pass, info); + include(gGlobalOptions, optSkipConfigFile); + end; + wSkipProjCfg: begin + expectNoArg(switch, arg, pass, info); + include(gGlobalOptions, optSkipProjConfigFile); + end; + wGenScript: begin + expectNoArg(switch, arg, pass, info); + include(gGlobalOptions, optGenScript); + end; + wLib: begin + expectArg(switch, arg, pass, info); + libpath := processPath(arg) + end; + wPutEnv: begin + expectArg(switch, arg, pass, info); + splitSwitch(arg, key, val, pass, info); + nos.putEnv(key, val); + end; + wCC: begin + expectArg(switch, arg, pass, info); + setCC(arg) + end; + wMaxErr: begin + expectArg(switch, arg, pass, info); + gErrorMax := parseInt(arg); + end; + else if strutils.find(switch, '.') >= strStart then + options.setConfigVar(switch, arg) + else + InvalidCmdLineOption(pass, switch, info) + end +end; + +procedure ProcessCommand(const switch: string; pass: TCmdLinePass); +var + cmd, arg: string; + info: TLineInfo; +begin + info := newLineInfo('command line', 1, 1); + splitSwitch(switch, cmd, arg, pass, info); + ProcessSwitch(cmd, arg, pass, info) +end; + +end. diff --git a/nim/condsyms.pas b/nim/condsyms.pas index 9c5d64d4b..1df513bbc 100644 --- a/nim/condsyms.pas +++ b/nim/condsyms.pas @@ -15,7 +15,7 @@ unit condsyms; interface uses - nsystem, ast, astalgo, msgs, hashes, platform, strutils, idents; + nsystem, ast, astalgo, msgs, nhashes, platform, strutils, idents; var gSymbols: TStrTable; diff --git a/nim/docgen.pas b/nim/docgen.pas index 15969f51d..784ab6c6c 100644 --- a/nim/docgen.pas +++ b/nim/docgen.pas @@ -18,7 +18,7 @@ interface {$include 'config.inc'} uses - nsystem, charsets, ast, astalgo, strutils, hashes, options, nversion, msgs, + nsystem, charsets, ast, astalgo, strutils, nhashes, options, nversion, msgs, nos, ropes, idents, wordrecg, nmath, pnimsyn, rnimsyn, scanner, rst, ntime, highlite; @@ -722,6 +722,16 @@ begin end end; +function renderContainer(d: PDoc; n: PRstNode): PRope; +var + arg: PRope; +begin + result := renderRstToHtml(d, n.sons[2]); + arg := toRope(strip(getArgument(n))); + if arg = nil then result := ropef('<div>$1</div>', [result]) + else result := ropef('<div class="$1">$2</div>', [arg, result]) +end; + function renderRstToHtml(d: PDoc; n: PRstNode): PRope; var outer, inner: string; @@ -811,6 +821,10 @@ begin result := renderCodeBlock(d, n); exit end; + rnContainer: begin + result := renderContainer(d, n); + exit + end; rnSubstitutionReferences, rnSubstitutionDef: outer := '|$1|'; rnDirective: outer := ''; diff --git a/nim/ecmasgen.pas b/nim/ecmasgen.pas index c9dfcfe25..2eecfba71 100644 --- a/nim/ecmasgen.pas +++ b/nim/ecmasgen.pas @@ -17,7 +17,7 @@ interface {$include 'config.inc'} uses - nsystem, ast, astalgo, strutils, hashes, trees, platform, magicsys, + nsystem, ast, astalgo, strutils, nhashes, trees, platform, magicsys, extccomp, options, nversion, nimsets, msgs, crc, bitsets, idents, lists, types, nos, ntime, ropes, nmath, passes, ccgutils, wordrecg, rnimsyn, rodread; diff --git a/nim/evals.pas b/nim/evals.pas index f9ca85c8f..218046c7e 100644 --- a/nim/evals.pas +++ b/nim/evals.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. @@ -157,7 +157,7 @@ begin end; var - gWhileCounter: int; // Use a counter to prevend endless loops! + gWhileCounter: int; // Use a counter to prevent endless loops! // We make this counter global, because otherwise // nested loops could make the compiler extremely slow. gNestedEvals: int; // count the recursive calls to ``evalAux`` to prevent @@ -390,7 +390,7 @@ begin stackTrace(c, n, errIndexOutOfBounds); end; else - stackTrace(c, n, errIndexNoIntType); + stackTrace(c, n, errNilAccess); end end; @@ -506,7 +506,8 @@ begin result := emptyNode end end; - if result = nil then InternalError(n.info, 'evalSym: ' + n.sym.name.s); + if result = nil then + stackTrace(c, n, errCannotInterpretNodeX, n.sym.name.s); end; function evalIncDec(c: PEvalContext; n: PNode; sign: biggestInt): PNode; @@ -563,8 +564,12 @@ function evalDeref(c: PEvalContext; n: PNode): PNode; begin result := evalAux(c, n.sons[0]); if result.kind = nkExceptBranch then exit; - if result.kind <> nkRefTy then InternalError(n.info, 'evalDeref'); - result := result.sons[0]; + case result.kind of + nkExceptBranch: exit; + nkNilLit: stackTrace(c, n, errNilAccess); + nkRefTy: result := result.sons[0]; + else InternalError(n.info, 'evalDeref ' + nodeKindToStr[result.kind]); + end; end; function evalAddr(c: PEvalContext; n: PNode): PNode; @@ -574,7 +579,6 @@ var begin result := evalAux(c, n.sons[0]); if result.kind = nkExceptBranch then exit; - if result.kind <> nkRefTy then InternalError(n.info, 'evalDeref'); a := result; t := newType(tyPtr, c.module); addSon(t, a.typ); @@ -732,6 +736,7 @@ end; function evalSetLengthSeq(c: PEvalContext; n: PNode): PNode; var a, b: PNode; + newLen, oldLen, i: int; begin result := evalAux(c, n.sons[1]); if result.kind = nkExceptBranch then exit; @@ -739,8 +744,12 @@ begin result := evalAux(c, n.sons[2]); if result.kind = nkExceptBranch then exit; b := result; - if a.kind = nkBracket then setLength(a.sons, int(getOrdValue(b))) - else InternalError(n.info, 'evalSetLengthSeq'); + if a.kind <> nkBracket then InternalError(n.info, 'evalSetLengthSeq'); + newLen := int(getOrdValue(b)); + oldLen := sonsLen(a); + setLength(a.sons, newLen); + for i := oldLen to newLen-1 do + a.sons[i] := getNullValue(skipVarGeneric(n.sons[1].typ), n.info); result := emptyNode end; @@ -758,10 +767,13 @@ begin b := result; t := skipVarGeneric(n.sons[1].typ); - result := newNodeIT(nkBracket, n.info, t); + if a.kind = nkEmpty then InternalError(n.info, 'first parameter is empty'); + a.kind := nkBracket; + a.info := n.info; + a.typ := t; for i := 0 to int(getOrdValue(b))-1 do - addSon(result, getNullValue(t.sons[0], n.info)); - // XXX: assign to `a`? result := emptyNode + addSon(a, getNullValue(t.sons[0], n.info)); + result := emptyNode end; function evalAssert(c: PEvalContext; n: PNode): PNode; @@ -907,7 +919,7 @@ end; function evalMagicOrCall(c: PEvalContext; n: PNode): PNode; var m: TMagic; - a, b: PNode; + a, b, cc: PNode; k: biggestInt; i: int; begin @@ -1179,22 +1191,35 @@ begin mNError: begin result := evalAux(c, n.sons[1]); if result.kind = nkExceptBranch then exit; - liMessage(n.info, errUser, getStrValue(result)); + stackTrace(c, n, errUser, getStrValue(result)); result := emptyNode end; mConStrStr: result := evalConStrStr(c, n); mRepr: result := evalRepr(c, n); + mNewString: begin + result := evalAux(c, n.sons[1]); + if result.kind = nkExceptBranch then exit; + a := result; + result := newNodeIT(nkStrLit, n.info, n.typ); + result.strVal := newString(int(getOrdValue(a))); + end; else begin result := evalAux(c, n.sons[1]); if result.kind = nkExceptBranch then exit; a := result; + b := nil; + cc := nil; if sonsLen(n) > 2 then begin result := evalAux(c, n.sons[2]); if result.kind = nkExceptBranch then exit; - end - else - result := nil; - result := evalOp(m, n, a, result); + b := result; + if sonsLen(n) > 3 then begin + result := evalAux(c, n.sons[3]); + if result.kind = nkExceptBranch then exit; + cc := result; + end + end; + result := evalOp(m, n, a, b, cc); end end end; @@ -1213,7 +1238,7 @@ begin nkNilLit: result := n; // end of atoms nkCall, nkHiddenCallConv, nkMacroStmt: result := evalMagicOrCall(c, n); - nkCurly, nkBracket: begin + nkCurly, nkBracket, nkRange: begin result := copyNode(n); for i := 0 to sonsLen(n)-1 do addSon(result, evalAux(c, n.sons[i])); end; diff --git a/nim/extccomp.pas b/nim/extccomp.pas index f51e5f690..a53ad1c10 100644 --- a/nim/extccomp.pas +++ b/nim/extccomp.pas @@ -15,8 +15,8 @@ interface {$include 'config.inc'} uses - nsystem, charsets, lists, ropes, nos, strutils, platform, condsyms, options, - msgs; + nsystem, charsets, lists, ropes, nos, strutils, osproc, platform, condsyms, + options, msgs; // some things are read in from the configuration file @@ -387,7 +387,7 @@ procedure execExternalProgram(const cmd: string); begin if (optListCmd in gGlobalOptions) or (gVerbosity > 0) then MessageOut('Executing: ' +{&} nl +{&} cmd); - if executeShellCommand(cmd) <> 0 then + if executeCommand(cmd) <> 0 then rawMessage(errExecutionOfProgramFailed); end; diff --git a/nim/hashtest.pas b/nim/hashtest.pas index ba7a62372..7e93ca5bf 100644 --- a/nim/hashtest.pas +++ b/nim/hashtest.pas @@ -3,7 +3,7 @@ program hashtest; {$include 'config.inc'} uses - hashes; + nhashes; begin writeln(output, getNormalizedHash(ParamStr(1))); diff --git a/nim/highlite.pas b/nim/highlite.pas index 5ef4acc12..ad7a6f724 100644 --- a/nim/highlite.pas +++ b/nim/highlite.pas @@ -17,7 +17,7 @@ interface {$include 'config.inc'} uses - charsets, nsystem, sysutils, hashes, options, msgs, strutils, platform, + charsets, nsystem, sysutils, nhashes, options, msgs, strutils, platform, idents, lexbase, wordrecg, scanner; type diff --git a/nim/idents.pas b/nim/idents.pas index c0e4c994f..c1c1755e9 100644 --- a/nim/idents.pas +++ b/nim/idents.pas @@ -17,7 +17,7 @@ unit idents; interface uses - hashes, nsystem, strutils; + nhashes, nsystem, strutils; type TIdObj = object(NObject) diff --git a/nim/interact.pas b/nim/interact.pas index ac238107f..aab3c7fc2 100644 --- a/nim/interact.pas +++ b/nim/interact.pas @@ -15,7 +15,7 @@ interface {$include 'config.inc'} uses - nsystem, llstream, strutils, charsets, ropes, strtabs, msgs; + nsystem, llstream, strutils, charsets, ropes, nstrtabs, msgs; implementation diff --git a/nim/magicsys.pas b/nim/magicsys.pas index 7a717e61d..462912995 100644 --- a/nim/magicsys.pas +++ b/nim/magicsys.pas @@ -16,7 +16,7 @@ interface uses nsystem, - ast, astalgo, hashes, msgs, platform, nversion, ntime, idents, rodread; + ast, astalgo, nhashes, msgs, platform, nversion, ntime, idents, rodread; var // magic symbols in the system module: SystemModule: PSym; diff --git a/nim/main.pas b/nim/main.pas index c888e5c3c..b1c58c2b9 100644 --- a/nim/main.pas +++ b/nim/main.pas @@ -152,7 +152,7 @@ begin semanticPasses(); registerPass(cgen.cgenPass()); registerPass(rodwrite.rodwritePass()); - registerPass(cleanupPass()); + //registerPass(cleanupPass()); compileProject(filename); //for i := low(TTypeKind) to high(TTypeKind) do // MessageOut('kind: ' +{&} typeKindToStr[i] +{&} ' = ' +{&} toString(sameTypeA[i])); diff --git a/nim/msgs.pas b/nim/msgs.pas index 0eb1651d9..53e1b3388 100644 --- a/nim/msgs.pas +++ b/nim/msgs.pas @@ -96,10 +96,10 @@ type errAttemptToRedefine, errStmtInvalidAfterReturn, errStmtExpected, - errYieldOnlyInInterators, errInvalidLabel, errInvalidCmdLineOption, errCmdLineArgExpected, + errCmdLineNoArgExpected, errInvalidVarSubstitution, errUnknownVar, errUnknownCcompiler, @@ -138,7 +138,7 @@ type errStaticAssertCannotBeEval, errDotRequiresRecordOrObjectType, errUndeclaredFieldX, - errIndexNoIntType, + errNilAccess, errIndexOutOfBounds, errIndexTypesDoNotMatch, errBracketsInvalidForType, @@ -348,17 +348,17 @@ const 'exception expected', 'exception already handled', '''return'' only allowed in routine', - '''yield'' only allowed in iterator', + '''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', - '''yield'' statement is only allowed in iterators', '''$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''', @@ -397,7 +397,7 @@ const 'argument to ''staticAssert'' cannot be evaluated at compile time', '''.'' requires a record or object type', 'undeclared field: ''$1''', - 'index has to be an integer type', + 'attempt to access a nil address', 'index out of bounds', 'index types do not match', '''[]'' operator invalid for this type', diff --git a/nim/hashes.pas b/nim/nhashes.pas index 0d7eb205d..0564f6f47 100644 --- a/nim/hashes.pas +++ b/nim/nhashes.pas @@ -6,7 +6,7 @@ // See the file "copying.txt", included in this // distribution, for details about the copyright. // -unit hashes; +unit nhashes; {$include 'config.inc'} diff --git a/nim/strtabs.pas b/nim/nstrtabs.pas index 4fcf32891..bcb10f2ed 100644 --- a/nim/strtabs.pas +++ b/nim/nstrtabs.pas @@ -6,7 +6,7 @@ // See the file "copying.txt", included in this // distribution, for details about the copyright. // -unit strtabs; +unit nstrtabs; // String tables. @@ -15,7 +15,7 @@ interface {$include 'config.inc'} uses - nsystem, nos, hashes, strutils; + nsystem, nos, nhashes, strutils; type TStringTableMode = ( @@ -93,9 +93,9 @@ end; function myhash(t: PStringTable; const key: string): THash; begin case t.mode of - modeCaseSensitive: result := hashes.GetHashStr(key); - modeCaseInsensitive: result := hashes.GetHashStrCI(key); - modeStyleInsensitive: result := hashes.getNormalizedHash(key); + modeCaseSensitive: result := nhashes.GetHashStr(key); + modeCaseInsensitive: result := nhashes.GetHashStrCI(key); + modeStyleInsensitive: result := nhashes.getNormalizedHash(key); end end; diff --git a/nim/nversion.pas b/nim/nversion.pas index de0ad2b79..ae6392db9 100644 --- a/nim/nversion.pas +++ b/nim/nversion.pas @@ -1,42 +1,42 @@ -// -// -// The Nimrod Compiler -// (c) Copyright 2008 Andreas Rumpf -// -// See the file "copying.txt", included in this -// distribution, for details about the copyright. -// - -unit nversion; - -// this unit implements the version handling - -interface - -{$include 'config.inc'} - -uses - strutils; - -const - MaxSetElements = 1 shl 16; // (2^16) to support unicode character sets? - defaultAsmMarkerSymbol = '!'; - - //[[[cog - //from koch import NIMROD_VERSION - //from string import split - //cog.outl("VersionAsString = '%s';" % NIMROD_VERSION) - //ver = split(NIMROD_VERSION, '.') - //cog.outl('VersionMajor = %s;' % ver[0]) - //cog.outl('VersionMinor = %s;' % ver[1]) - //cog.outl('VersionPatch = %s;' % ver[2]) - //]]] - VersionAsString = '0.7.6'; +// +// +// The Nimrod Compiler +// (c) Copyright 2008 Andreas Rumpf +// +// See the file "copying.txt", included in this +// distribution, for details about the copyright. +// + +unit nversion; + +// this unit implements the version handling + +interface + +{$include 'config.inc'} + +uses + strutils; + +const + MaxSetElements = 1 shl 16; // (2^16) to support unicode character sets? + defaultAsmMarkerSymbol = '!'; + + //[[[cog + //from koch import NIMROD_VERSION + //from string import split + //cog.outl("VersionAsString = '%s';" % NIMROD_VERSION) + //ver = split(NIMROD_VERSION, '.') + //cog.outl('VersionMajor = %s;' % ver[0]) + //cog.outl('VersionMinor = %s;' % ver[1]) + //cog.outl('VersionPatch = %s;' % ver[2]) + //]]] + VersionAsString = '0.7.8'; VersionMajor = 0; VersionMinor = 7; - VersionPatch = 6; - //[[[[end]]]] - -implementation - -end. + VersionPatch = 8; + //[[[[end]]]] + +implementation + +end. diff --git a/nim/options.pas b/nim/options.pas index d6f6d14da..f84d8458c 100644 --- a/nim/options.pas +++ b/nim/options.pas @@ -13,7 +13,7 @@ interface {$include 'config.inc'} uses - nsystem, nos, lists, strutils, strtabs; + nsystem, nos, lists, strutils, nstrtabs; type // please make sure we have under 32 options @@ -150,12 +150,12 @@ end; function getConfigVar(const key: string): string; begin - result := strtabs.get(gConfigVars, key); + result := nstrtabs.get(gConfigVars, key); end; procedure setConfigVar(const key, val: string); begin - strtabs.put(gConfigVars, key, val); + nstrtabs.put(gConfigVars, key, val); end; function getOutFile(const filename, ext: string): string; diff --git a/nim/osproc.pas b/nim/osproc.pas new file mode 100644 index 000000000..dd6bd10f0 --- /dev/null +++ b/nim/osproc.pas @@ -0,0 +1,30 @@ +// +// +// The Nimrod Compiler +// (c) Copyright 2009 Andreas Rumpf +// +// See the file "copying.txt", included in this +// distribution, for details about the copyright. +// +unit osproc; + +// This module provides Nimrod's osproc module in Pascal +// Note: Only implement what is really needed here! + +interface + +{$include 'config.inc'} + +uses + nsystem, nos; + +function executeCommand(const cmd: string): int; + +implementation + +function executeCommand(const cmd: string): int; +begin + result := executeShellCommand(cmd); +end; + +end. diff --git a/nim/parsecfg.pas b/nim/parsecfg.pas index 3c10cc8fc..620335aa6 100644 --- a/nim/parsecfg.pas +++ b/nim/parsecfg.pas @@ -17,7 +17,7 @@ interface {$include 'config.inc'} uses - nsystem, charsets, llstream, sysutils, hashes, strutils, lexbase; + nsystem, charsets, llstream, sysutils, nhashes, strutils, lexbase; type TCfgEventKind = ( diff --git a/nim/paslex.pas b/nim/paslex.pas index c0136e4d8..da9283163 100644 --- a/nim/paslex.pas +++ b/nim/paslex.pas @@ -17,7 +17,7 @@ interface uses charsets, nsystem, sysutils, - hashes, options, msgs, strutils, platform, idents, + nhashes, options, msgs, strutils, platform, idents, lexbase, wordrecg, scanner; const diff --git a/nim/pragmas.pas b/nim/pragmas.pas index 9a60e6bd3..df48f27c9 100644 --- a/nim/pragmas.pas +++ b/nim/pragmas.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. @@ -143,7 +143,7 @@ begin else v := expectStrLit(c, n); Include(s.flags, sfImportc); // magics don't need an implementation, so we // treat them as imported, instead of modifing a lot of working code - Include(s.loc.Flags, lfNoDecl); // magics don't need to be declared! + // BUGFIX: magic does not imply ``lfNoDecl`` anymore! for m := low(TMagic) to high(TMagic) do if magicToStr[m] = v then begin s.magic := m; exit diff --git a/nim/ropes.pas b/nim/ropes.pas index 864afd5b8..6b6540c24 100644 --- a/nim/ropes.pas +++ b/nim/ropes.pas @@ -64,7 +64,7 @@ interface {$include 'config.inc'} uses - nsystem, msgs, strutils, platform, hashes, crc; + nsystem, msgs, strutils, platform, nhashes, crc; const CacheLeafs = true; diff --git a/nim/rst.pas b/nim/rst.pas index 0c5377646..6d0d476c9 100644 --- a/nim/rst.pas +++ b/nim/rst.pas @@ -16,7 +16,7 @@ interface {$include 'config.inc'} uses - nsystem, nos, msgs, strutils, platform, hashes, ropes, charsets, options; + nsystem, nos, msgs, strutils, platform, nhashes, ropes, charsets, options; type TRstNodeKind = ( @@ -79,6 +79,7 @@ type rnImage, rnFigure, rnCodeBlock, + rnContainer, // ``container`` directive rnIndex, // index directve: // .. index:: // key @@ -111,9 +112,9 @@ const 'TableRow', 'TableHeaderCell', 'TableDataCell', 'Label', 'Footnote', 'Citation', 'StandaloneHyperlink', 'Hyperlink', 'Ref', 'Directive', 'DirArg', 'Raw', 'Title', 'Contents', 'Image', 'Figure', 'CodeBlock', - 'Index', 'SubstitutionDef', 'GeneralRole', 'Sub', 'Sup', 'Idx', - 'Emphasis', 'StrongEmphasis', 'InterpretedText', 'InlineLiteral', - 'SubstitutionReferences', 'Leaf' + 'Container', 'Index', 'SubstitutionDef', 'GeneralRole', + 'Sub', 'Sup', 'Idx', 'Emphasis', 'StrongEmphasis', 'InterpretedText', + 'InlineLiteral', 'SubstitutionReferences', 'Leaf' ); type @@ -1178,12 +1179,12 @@ end; type TDirKind = ( // must be ordered alphabetically! - dkNone, dkAuthor, dkAuthors, dkCodeBlock, + dkNone, dkAuthor, dkAuthors, dkCodeBlock, dkContainer, dkContents, dkFigure, dkImage, dkInclude, dkIndex, dkRaw, dkTitle ); const - DirIds: array [0..10] of string = ( - '', 'author', 'authors', 'code-block', + DirIds: array [0..11] of string = ( + '', 'author', 'authors', 'code-block', 'container', 'contents', 'figure', 'image', 'include', 'index', 'raw', 'title' ); @@ -1993,6 +1994,14 @@ begin result.kind := rnCodeBlock end; +function dirContainer(var p: TRstParser): PRstNode; +begin + result := parseDirective(p, {@set}[hasArg], parseSectionWrapper); + assert(result.kind = rnDirective); + assert(rsonsLen(result) = 3); + result.kind := rnContainer; +end; + function dirImage(var p: TRstParser): PRstNode; begin result := parseDirective(p, {@set}[hasOptions, hasArg, argIsFile], nil); @@ -2071,6 +2080,7 @@ begin dkImage: result := dirImage(p); dkFigure: result := dirFigure(p); dkTitle: result := dirTitle(p); + dkContainer: result := dirContainer(p); dkContents: result := dirContents(p); dkRaw: result := dirRaw(p); dkCodeblock: result := dirCodeBlock(p); diff --git a/nim/scanner.pas b/nim/scanner.pas index d035b973b..51532c801 100644 --- a/nim/scanner.pas +++ b/nim/scanner.pas @@ -21,7 +21,7 @@ interface {$include 'config.inc'} uses - charsets, nsystem, sysutils, hashes, options, msgs, strutils, platform, + charsets, nsystem, sysutils, nhashes, options, msgs, strutils, platform, idents, lexbase, llstream, wordrecg; const diff --git a/nim/sem.pas b/nim/sem.pas index 3494754fd..09f9bf49b 100644 --- a/nim/sem.pas +++ b/nim/sem.pas @@ -112,6 +112,23 @@ begin end end; +function semAfterMacroCall(c: PContext; n, p: PNode): PNode; +begin + result := n; + if (p = nil) or (p.kind <> nkIdent) then + liMessage(n.info, errInvalidParamKindX, renderTree(p)) + else begin + case p.ident.id of + ord(wExpr): result := semExprWithType(c, result); + ord(wStmt): result := semStmt(c, result); + ord(wTypeDesc): + result.typ := semTypeNode(c, result, nil); + else + liMessage(p.info, errInvalidParamKindX, p.ident.s) + end + end +end; + function semMacroExpr(c: PContext; n: PNode; sym: PSym): PNode; var p: PEvalContext; @@ -128,7 +145,7 @@ begin result := s.params[0]; popStackFrame(p); if cyclicTree(result) then liMessage(n.info, errCyclicTree); - result := semStmt(c, result); + result := semAfterMacroCall(c, result, sym.ast.sons[paramsPos].sons[0]); // now, that was easy ... // and we get more flexibility than in any other programming language end; @@ -137,14 +154,12 @@ end; {$include 'seminst.pas'} {$include 'sigmatch.pas'} - procedure CheckBool(t: PNode); begin if (t.Typ = nil) or (skipVarGeneric(t.Typ).kind <> tyBool) then liMessage(t.Info, errExprMustBeBool); end; - procedure typeMismatch(n: PNode; formal, actual: PType); begin liMessage(n.Info, errGenerated, @@ -167,13 +182,17 @@ var prc: PSym; it: PNode; begin - for i := 0 to sonsLen(c.generics)-1 do begin + for i := c.lastGenericIdx to sonsLen(c.generics)-1 do begin it := c.generics.sons[i].sons[1]; if it.kind <> nkSym then InternalError('addCodeForGenerics'); prc := it.sym; - if (prc.kind in [skProc, skConverter]) and (prc.magic = mNone) then + if (prc.kind in [skProc, skConverter]) and (prc.magic = mNone) then begin + if (prc.ast = nil) or (prc.ast.sons[codePos] = nil) then + InternalError(prc.info, 'no code for ' + prc.name.s); addSon(n, prc.ast); + end end; + c.lastGenericIdx := sonsLen(c.generics); end; function myOpen(module: PSym; const filename: string): PPassContext; @@ -212,10 +231,21 @@ end; function myProcess(context: PPassContext; n: PNode): PNode; var c: PContext; + a: PNode; begin result := nil; c := PContext(context); result := semStmt(c, n); + // BUGFIX: process newly generated generics here, not at the end! + if sonsLen(c.generics) > 0 then begin + a := newNodeI(nkStmtList, n.info); + addCodeForGenerics(c, a); + if sonsLen(a) > 0 then begin + // a generic has been added to `a`: + addSonIfNotNil(a, result); + result := a + end + end end; function myClose(context: PPassContext; n: PNode): PNode; @@ -226,7 +256,8 @@ begin closeScope(c.tab); // close module's scope rawCloseScope(c.tab); // imported symbols; don't check for unused ones! if n = nil then result := newNode(nkStmtList) - else result := n; + else InternalError(n.info, 'n is not nil'); + //result := n; addCodeForGenerics(c, result); popOwner(); c.p := nil; diff --git a/nim/semdata.pas b/nim/semdata.pas index 3393ed4b3..acca48376 100644 --- a/nim/semdata.pas +++ b/nim/semdata.pas @@ -55,6 +55,7 @@ type libs: TLinkedList; // all libs used by this module p: PProcCon; // procedure context fromCache: bool; // is the module read from a cache? + lastGenericIdx: int; // used for the generics stack semConstExpr: function (c: PContext; n: PNode): PNode; // for the pragmas module end; diff --git a/nim/semfold.pas b/nim/semfold.pas index 781c3b97d..fdbad9f4c 100644 --- a/nim/semfold.pas +++ b/nim/semfold.pas @@ -24,7 +24,7 @@ function getConstExpr(module: PSym; n: PNode): PNode; // evaluates the constant expression or returns nil if it is no constant // expression -function evalOp(m: TMagic; n, a, b: PNode): PNode; +function evalOp(m: TMagic; n, a, b, c: PNode): PNode; function leValueConv(a, b: PNode): Boolean; function newIntNodeT(const intVal: BiggestInt; n: PNode): PNode; @@ -113,8 +113,8 @@ begin InternalError(a.info, 'no symbol for ordinal value: ' + toString(x)); end; -function evalOp(m: TMagic; n, a, b: PNode): PNode; -// if this is an unary operation, b is nil +function evalOp(m: TMagic; n, a, b, c: PNode): PNode; +// b and c may be nil begin result := nil; case m of @@ -127,8 +127,9 @@ begin mBitnotI, mBitnotI64: result := newIntNodeT(not getInt(a), n); mLengthStr: result := newIntNodeT(length(getStr(a)), n); - mLengthSeq, mLengthArray, - mLengthOpenArray: result := newIntNodeT(lengthOrd(a.typ), n); + mLengthArray: result := newIntNodeT(lengthOrd(a.typ), n); + mLengthSeq, mLengthOpenArray: + result := newIntNodeT(sonsLen(a), n); // BUGFIX mUnaryPlusI, mUnaryPlusI64, mUnaryPlusF64: result := a; // throw `+` away mToFloat, mToBiggestFloat: @@ -273,6 +274,11 @@ begin else result := newStrNodeT('true', n) end; + mCopyStr: + result := newStrNodeT(ncopy(getStr(a), int(getOrdValue(b))+strStart), n); + mCopyStrLast: + result := newStrNodeT(ncopy(getStr(a), int(getOrdValue(b))+strStart, + int(getOrdValue(c))+strStart), n); mFloatToStr: result := newStrNodeT(toStringF(getFloat(a)), n); mCStrToStr, mCharToStr: result := newStrNodeT(getStrOrChar(a), n); mStrToStr: result := a; @@ -281,7 +287,7 @@ begin result := copyTree(a); result.typ := n.typ; end; - mExit, mInc, ast.mDec, mAssert, mSwap, + mNewString, mExit, mInc, ast.mDec, mAssert, mSwap, mAppendStrCh, mAppendStrStr, mAppendSeqElem, mAppendSeqSeq, mSetLengthStr, mSetLengthSeq, mNLen..mNError: begin end; else InternalError(a.info, 'evalOp(' +{&} magicToStr[m] +{&} ')'); @@ -376,7 +382,7 @@ end; function getConstExpr(module: PSym; n: PNode): PNode; var s: PSym; - a, b: PNode; + a, b, c: PNode; i: int; begin result := nil; @@ -443,10 +449,14 @@ begin if a = nil then exit; if sonsLen(n) > 2 then begin b := getConstExpr(module, n.sons[2]); - if b = nil then exit + if b = nil then exit; + if sonsLen(n) > 3 then begin + c := getConstExpr(module, n.sons[3]); + if c = nil then exit; + end end else b := nil; - result := evalOp(s.magic, n, a, b); + result := evalOp(s.magic, n, a, b, c); end end except diff --git a/nim/semstmts.pas b/nim/semstmts.pas index ebf14693c..a5242b526 100644 --- a/nim/semstmts.pas +++ b/nim/semstmts.pas @@ -354,7 +354,8 @@ var begin result := n; checkSonsLen(n, 1); - if (c.p.owner = nil) or (c.p.owner.kind <> skIterator) then + if (c.p.owner = nil) or (c.p.owner.kind <> skIterator) + or (c.p.nestedLoopCounter <= 0) then liMessage(n.info, errYieldNotAllowedHere); if (n.sons[0] <> nil) then begin n.sons[0] := SemExprWithType(c, n.sons[0]); diff --git a/nim/tigen.pas b/nim/tigen.pas index 937883e5e..687b70920 100644 --- a/nim/tigen.pas +++ b/nim/tigen.pas @@ -17,7 +17,7 @@ interface {$include 'config.inc'} uses - nsystem, ast, astalgo, strutils, hashes, trees, treetab, platform, magicsys, + nsystem, ast, astalgo, strutils, nhashes, trees, treetab, platform, magicsys, options, msgs, crc, idents, lists, types, rnimsyn; function gcWalker(t: PType): PNode; diff --git a/nim/transf.pas b/nim/transf.pas index 5d9f44143..c4ed5740c 100644 --- a/nim/transf.pas +++ b/nim/transf.pas @@ -801,7 +801,7 @@ begin inc(j); if isConstExpr(a) then while (j < sonsLen(m)) and isConstExpr(m.sons[j]) do begin - a := evalOp(op.magic, m, a, m.sons[j]); + a := evalOp(op.magic, m, a, m.sons[j], nil); inc(j) end; addSon(result, a); diff --git a/nim/treetab.pas b/nim/treetab.pas index dbd7b5276..31d7aa0cf 100644 --- a/nim/treetab.pas +++ b/nim/treetab.pas @@ -15,7 +15,7 @@ interface {$include 'config.inc'} uses - nsystem, hashes, ast, astalgo, types; + nsystem, nhashes, ast, astalgo, types; function NodeTableGet(const t: TNodeTable; key: PNode): int; procedure NodeTablePut(var t: TNodeTable; key: PNode; val: int); diff --git a/nim/wordrecg.pas b/nim/wordrecg.pas index dd2df0047..7957d354b 100644 --- a/nim/wordrecg.pas +++ b/nim/wordrecg.pas @@ -19,7 +19,7 @@ interface {$include 'config.inc'} uses - nsystem, hashes, strutils, idents; + nsystem, nhashes, strutils, idents; type TSpecialWord = (wInvalid, |