diff options
author | Andreas Rumpf <andreas@andreas-laptop> | 2010-04-02 19:34:57 +0200 |
---|---|---|
committer | Andreas Rumpf <andreas@andreas-laptop> | 2010-04-02 19:34:57 +0200 |
commit | f530bbd6315f21469d7479991186e88302608726 (patch) | |
tree | 8b05aba5a3d407d50160c448fa2ba5b2fa952a6f /rod | |
parent | 227b76c34259cf406131d27fb8e0cc88530e38f7 (diff) | |
download | Nim-f530bbd6315f21469d7479991186e88302608726.tar.gz |
tiny C backend for a much faster REPL
Diffstat (limited to 'rod')
-rwxr-xr-x | rod/cgen.nim | 48 | ||||
-rwxr-xr-x | rod/commands.nim | 2 | ||||
-rwxr-xr-x | rod/evals.nim | 6 | ||||
-rwxr-xr-x | rod/extccomp.nim | 6 | ||||
-rwxr-xr-x | rod/main.nim | 12 | ||||
-rwxr-xr-x | rod/msgs.nim | 12 | ||||
-rwxr-xr-x | rod/nimrod.nim | 15 | ||||
-rwxr-xr-x | rod/options.nim | 6 | ||||
-rwxr-xr-x | rod/ropes.nim | 8 |
9 files changed, 75 insertions, 40 deletions
diff --git a/rod/cgen.nim b/rod/cgen.nim index 989778a02..ad322a1dd 100755 --- a/rod/cgen.nim +++ b/rod/cgen.nim @@ -1,7 +1,7 @@ # # # The Nimrod Compiler -# (c) Copyright 2009 Andreas Rumpf +# (c) Copyright 2010 Andreas Rumpf # # See the file "copying.txt", included in this # distribution, for details about the copyright. @@ -15,6 +15,9 @@ import nversion, nimsets, msgs, crc, bitsets, idents, lists, types, ccgutils, os, times, ropes, math, passes, rodread, wordrecg, rnimsyn, treetab, cgmeth +when options.hasTinyCBackend: + import tccgen + proc cgenPass*(): TPass # implementation @@ -518,7 +521,8 @@ proc genProcAux(m: BModule, prc: PSym) = if p.beforeRetNeeded: app(generatedProc, "BeforeRet: ;" & tnl) if optStackTrace in prc.options: app(generatedProc, deinitFrame(p)) if (optProfiler in prc.options) and (gCmd != cmdCompileToLLVM): - appf(generatedProc, "profileData[$1].total += elapsed(getticks(), NIM_profilingStart);$n", + appf(generatedProc, + "profileData[$1].total += elapsed(getticks(), NIM_profilingStart);$n", [toRope(prc.loc.a)]) app(generatedProc, returnStmt) app(generatedProc, '}' & tnl) @@ -600,13 +604,15 @@ proc genConstPrototype(m: BModule, sym: PSym) = proc getFileHeader(cfilenoext: string): PRope = if optCompileOnly in gGlobalOptions: result = ropeff("/* Generated by Nimrod Compiler v$1 */$n" & - "/* (c) 2009 Andreas Rumpf */$n", "; Generated by Nimrod Compiler v$1$n" & - "; (c) 2009 Andreas Rumpf$n", [toRope(versionAsString)]) + "/* (c) 2010 Andreas Rumpf */$n", + "; Generated by Nimrod Compiler v$1$n" & + "; (c) 2010 Andreas Rumpf$n", [toRope(versionAsString)]) else: result = ropeff("/* Generated by Nimrod Compiler v$1 */$n" & - "/* (c) 2009 Andreas Rumpf */$n" & "/* Compiled for: $2, $3, $4 */$n" & - "/* Command for C compiler:$n $5 */$n", "; Generated by Nimrod Compiler v$1$n" & - "; (c) 2009 Andreas Rumpf$n" & "; Compiled for: $2, $3, $4$n" & + "/* (c) 2010 Andreas Rumpf */$n" & "/* Compiled for: $2, $3, $4 */$n" & + "/* Command for C compiler:$n $5 */$n", + "; Generated by Nimrod Compiler v$1$n" & + "; (c) 2010 Andreas Rumpf$n" & "; Compiled for: $2, $3, $4$n" & "; Command for LLVM compiler:$n $5$n", [toRope(versionAsString), toRope(platform.OS[targetOS].name), toRope(platform.CPU[targetCPU].name), @@ -668,7 +674,8 @@ proc genMainProc(m: BModule) = " LPVOID lpvReserved) {$n" & " NimMain();$n" & " return 1;$n" & "}$n" WinNimDllMainLLVM = WinNimMainLLVM - WinCDllMainLLVM = "define stdcall i32 @DllMain(i32 %hinstDLL, i32 %fwdreason, $n" & + WinCDllMainLLVM = + "define stdcall i32 @DllMain(i32 %hinstDLL, i32 %fwdreason, $n" & " i8* %lpvReserved) {$n" & " call void @NimMain()$n" & " ret i32 1$n" & "}$n" var nimMain, otherMain: TFormatStr @@ -795,13 +802,13 @@ proc myOpen(module: PSym, filename: string): PPassContext = if gNimDat == nil: registerTypeInfoModule() result = newModule(module, filename) -proc myOpenCached(module: PSym, filename: string, rd: PRodReader): PPassContext = - var cfile, cfilenoext, objFile: string +proc myOpenCached(module: PSym, filename: string, + rd: PRodReader): PPassContext = if gNimDat == nil: registerTypeInfoModule() #MessageOut('cgen.myOpenCached has been called ' + filename); - cfile = changeFileExt(completeCFilePath(filename), cExt) - cfilenoext = changeFileExt(cfile, "") + var cfile = changeFileExt(completeCFilePath(filename), cExt) + var cfilenoext = changeFileExt(cfile, "") addFileToLink(cfilenoext) registerModuleToMain(module) # XXX: this cannot be right here, initalization has to be appended during @@ -838,18 +845,21 @@ proc finishModule(m: BModule) = setlen(m.forwardedProcs, 0) proc writeModule(m: BModule) = - var - cfile, cfilenoext: string - code: PRope # generate code for the init statements of the module: genInitCode(m) finishTypeDescriptions(m) - cfile = completeCFilePath(m.cfilename) - cfilenoext = changeFileExt(cfile, "") + var cfile = completeCFilePath(m.cfilename) + var cfilenoext = changeFileExt(cfile, "") if sfMainModule in m.module.flags: # generate main file: app(m.s[cfsProcHeaders], mainModProcs) - code = genModule(m, cfilenoext) + var code = genModule(m, cfilenoext) + + when hasTinyCBackend: + if gCmd == cmdRun: + tccgen.compileCCode(ropeToStr(code)) + return + if shouldRecompile(code, changeFileExt(cfile, cExt), cfilenoext): addFileToCompile(cfilenoext) addFileToLink(cfilenoext) @@ -867,7 +877,7 @@ proc myClose(b: PPassContext, n: PNode): PNode = finishModule(m) if sfMainModule in m.module.flags: var disp = generateMethodDispatchers() - for i in countup(0, sonsLen(disp) - 1): genProcAux(gNimDat, disp.sons[i].sym) + for i in 0..sonsLen(disp)-1: genProcAux(gNimDat, disp.sons[i].sym) genMainProc(m) # we need to process the transitive closure because recursive module # deps are allowed (and the system module is processed in the wrong diff --git a/rod/commands.nim b/rod/commands.nim index 17c946292..01b015b53 100755 --- a/rod/commands.nim +++ b/rod/commands.nim @@ -36,6 +36,7 @@ Usage:: Command:: compile, c compile project with default code generator (C) compileToC, cc compile project with C code generator + run compile the project in memory and run it doc generate the documentation for inputfile rst2html converts a reStructuredText file to HTML rst2tex converts a reStructuredText file to TeX @@ -70,7 +71,6 @@ Options: AdvancedUsage = """ Advanced commands:: - pas convert a Pascal file to Nimrod syntax pretty pretty print the inputfile genDepend generate a DOT file containing the module dependency graph diff --git a/rod/evals.nim b/rod/evals.nim index 79428e60f..7306f61b1 100755 --- a/rod/evals.nim +++ b/rod/evals.nim @@ -1014,9 +1014,9 @@ proc evalAux(c: PEvalContext, n: PNode, flags: TEvalFlags): PNode = case result.kind of nkExceptBranch, nkReturnToken, nkBreakStmt: break else: nil - of nkProcDef, nkMethodDef, nkMacroDef, nkCommentStmt, nkPragma, nkTypeSection, - nkTemplateDef, nkConstSection, nkIteratorDef, nkConverterDef, - nkIncludeStmt, nkImportStmt, nkFromStmt: + of nkProcDef, nkMethodDef, nkMacroDef, nkCommentStmt, nkPragma, + nkTypeSection, nkTemplateDef, nkConstSection, nkIteratorDef, + nkConverterDef, nkIncludeStmt, nkImportStmt, nkFromStmt: nil of nkIdentDefs, nkCast, nkYieldStmt, nkAsmStmt, nkForStmt, nkPragmaExpr, nkLambda, nkContinueStmt, nkIdent: diff --git a/rod/extccomp.nim b/rod/extccomp.nim index 563434e0f..a565bee72 100755 --- a/rod/extccomp.nim +++ b/rod/extccomp.nim @@ -1,7 +1,7 @@ # # # The Nimrod Compiler -# (c) Copyright 2009 Andreas Rumpf +# (c) Copyright 2010 Andreas Rumpf # # See the file "copying.txt", included in this # distribution, for details about the copyright. @@ -480,8 +480,8 @@ proc genMappingFiles(list: TLinkedList): PRope = it = PStrEntry(it.next) proc writeMapping(gSymbolMapping: PRope) = - if not (optGenMapping in gGlobalOptions): return - var code = toRope("[C_Files]" & "\n") + if optGenMapping notin gGlobalOptions: return + var code = toRope("[C_Files]\n") app(code, genMappingFiles(toCompile)) app(code, genMappingFiles(externalToCompile)) appf(code, "[Symbols]$n$1", [gSymbolMapping]) diff --git a/rod/main.nim b/rod/main.nim index 3221f531e..2a261bfe5 100755 --- a/rod/main.nim +++ b/rod/main.nim @@ -118,7 +118,8 @@ proc CommandCompileToC(filename: string) = registerPass(rodwrite.rodwritePass()) #registerPass(cleanupPass()) compileProject(filename) - extccomp.CallCCompiler(changeFileExt(filename, "")) + if gCmd != cmdRun: + extccomp.CallCCompiler(changeFileExt(filename, "")) when has_LLVM_Backend: proc CommandCompileToLLVM(filename: string) = @@ -191,6 +192,13 @@ proc MainCommand(cmd, filename: string) = gCmd = cmdCompileToC wantFile(filename) CommandCompileToC(filename) + of wRun: + gCmd = cmdRun + wantFile(filename) + when hasTinyCBackend: + CommandCompileToC(filename) + else: + rawMessage(errInvalidCommandX, cmd) of wCompileToCpp: gCmd = cmdCompileToCpp wantFile(filename) @@ -204,6 +212,8 @@ proc MainCommand(cmd, filename: string) = wantFile(filename) when has_LLVM_Backend: CommandCompileToLLVM(filename) + else: + rawMessage(errInvalidCommandX, cmd) of wPretty: gCmd = cmdPretty wantFile(filename) #CommandExportSymbols(filename); diff --git a/rod/msgs.nim b/rod/msgs.nim index 01852e0ba..ff42bc690 100755 --- a/rod/msgs.nim +++ b/rod/msgs.nim @@ -1,7 +1,7 @@ # # # The Nimrod Compiler -# (c) Copyright 2009 Andreas Rumpf +# (c) Copyright 2010 Andreas Rumpf # # See the file "copying.txt", included in this # distribution, for details about the copyright. @@ -298,14 +298,18 @@ const type TNoteKind* = range[warnMin..hintMax] # "notes" are warnings or hints TNoteKinds* = set[TNoteKind] - TLineInfo*{.final.} = object # This is designed to be as small as possible, because it is used - # in syntax nodes. We safe space here by using two int16 and an int32 - # on 64 bit and on 32 bit systems this is only 8 bytes. + TLineInfo*{.final.} = object # This is designed to be as small as possible, + # because it is used + # in syntax nodes. We safe space here by using + # two int16 and an int32 + # on 64 bit and on 32 bit systems this is + # only 8 bytes. line*, col*: int16 fileIndex*: int32 proc UnknownLineInfo*(): TLineInfo + var gNotes*: TNoteKinds = {low(TNoteKind)..high(TNoteKind)} gErrorCounter*: int = 0 # counts the number of errors diff --git a/rod/nimrod.nim b/rod/nimrod.nim index a6f3365c2..26bfcde2d 100755 --- a/rod/nimrod.nim +++ b/rod/nimrod.nim @@ -11,6 +11,9 @@ import times, commands, scanner, condsyms, options, msgs, nversion, nimconf, ropes, extccomp, strutils, os, platform, main, parseopt +when hasTinyCBackend: + import tccgen + var arguments: string = "" # the arguments to be passed to the program that # should be run @@ -21,8 +24,7 @@ proc ProcessCmdLine(pass: TCmdLinePass, command, filename: var string) = while true: parseopt.next(p) case p.kind - of cmdEnd: - break + of cmdEnd: break of cmdLongOption, cmdShortOption: # hint[X]:off is parsed as (p.key = "hint[X]", p.val = "off") # we fix this here @@ -41,7 +43,7 @@ proc ProcessCmdLine(pass: TCmdLinePass, command, filename: var string) = break if pass == passCmd2: arguments = cmdLineRest(p) - if not (optRun in gGlobalOptions) and (arguments != ""): + if optRun notin gGlobalOptions and arguments != "": rawMessage(errArgsNeedRunOption, []) proc HandleCmdLine() = @@ -63,8 +65,11 @@ proc HandleCmdLine() = ProcessCmdLine(passCmd2, command, filename) MainCommand(command, filename) if gVerbosity >= 2: echo(GC_getStatistics()) - if (gCmd != cmdInterpret) and (msgs.gErrorCounter == 0): - rawMessage(hintSuccessX, [$(gLinesCompiled), $(getTime() - start)]) + when hasTinyCBackend: + if gCmd == cmdRun: + tccgen.run() + if gCmd notin {cmdInterpret, cmdRun} and msgs.gErrorCounter == 0: + rawMessage(hintSuccessX, [$gLinesCompiled, $(getTime() - start)]) if optRun in gGlobalOptions: when defined(unix): var prog = "./" & quoteIfContainsWhite(changeFileExt(filename, "")) diff --git a/rod/options.nim b/rod/options.nim index 514c3db3b..9ce54a41c 100755 --- a/rod/options.nim +++ b/rod/options.nim @@ -9,6 +9,9 @@ import os, lists, strutils, nstrtabs + +const + hasTinyCBackend* = true type # please make sure we have under 32 options # (improves code efficiency a lot!) @@ -48,7 +51,8 @@ type # please make sure we have under 32 options cmdDebugTrans, # debug a transformation pass cmdRst2html, # convert a reStructuredText file to HTML cmdRst2tex, # convert a reStructuredText file to TeX - cmdInteractive # start interactive session + cmdInteractive, # start interactive session + cmdRun # run the project via TCC backend TStringSeq* = seq[string] const diff --git a/rod/ropes.nim b/rod/ropes.nim index 1fe5ed55e..0139daf2b 100755 --- a/rod/ropes.nim +++ b/rod/ropes.nim @@ -67,10 +67,12 @@ const type TFormatStr* = string # later we may change it to CString for better - # performance of the code generator (assignments copy the format strings + # performance of the code generator (assignments + # copy the format strings # though it is not necessary) PRope* = ref TRope - TRope*{.acyclic.} = object of TObject # the empty rope is represented by nil to safe space + TRope*{.acyclic.} = object of TObject # the empty rope is represented + # by nil to safe space left*, right*: PRope length*: int data*: string # != nil if a leaf @@ -405,4 +407,4 @@ proc writeRopeIfNotEqual(r: PRope, filename: string): bool = else: result = false -new(N) # init dummy node for splay algorithm \ No newline at end of file +new(N) # init dummy node for splay algorithm |