mirror of
https://github.com/nim-lang/Nim.git
synced 2026-04-29 10:43:57 +00:00
tiny C backend for a much faster REPL
This commit is contained in:
@@ -17,7 +17,7 @@ elif defined(darwin):
|
||||
lib = "gdk-x11-2.0"
|
||||
else:
|
||||
const
|
||||
lib = "libgdk-x11-2.0.so"
|
||||
lib = "libgdk-x11-2.0.so(|.0)"
|
||||
const
|
||||
NUMPTSTOBUFFER* = 200
|
||||
MAX_TIMECOORD_AXES* = 128
|
||||
|
||||
118
lib/wrappers/tinyc.nim
Normal file
118
lib/wrappers/tinyc.nim
Normal file
@@ -0,0 +1,118 @@
|
||||
#
|
||||
#
|
||||
# Nimrod's Runtime Library
|
||||
# (c) Copyright 2010 Andreas Rumpf
|
||||
#
|
||||
# See the file "copying.txt", included in this
|
||||
# distribution, for details about the copyright.
|
||||
#
|
||||
|
||||
type
|
||||
TccState {.pure, final.} = object
|
||||
PccState* = ptr TccState
|
||||
|
||||
TErrorFunc* = proc (opaque: pointer, msg: cstring) {.cdecl.}
|
||||
|
||||
proc openCCState*(): PccState {.importc: "tcc_new", cdecl.}
|
||||
## create a new TCC compilation context
|
||||
|
||||
proc closeCCState*(s: PccState) {.importc: "tcc_delete", cdecl.}
|
||||
## free a TCC compilation context
|
||||
|
||||
proc enableDebug*(s: PccState) {.importc: "tcc_enable_debug", cdecl.}
|
||||
## add debug information in the generated code
|
||||
|
||||
proc setErrorFunc*(s: PccState, errorOpaque: pointer, errorFun: TErrorFunc) {.
|
||||
cdecl, importc: "tcc_set_error_func".}
|
||||
## set error/warning display callback
|
||||
|
||||
proc setWarning*(s: PccState, warningName: cstring, value: int) {.cdecl,
|
||||
importc: "tcc_set_warning".}
|
||||
## set/reset a warning
|
||||
|
||||
# preprocessor
|
||||
|
||||
proc addIncludePath*(s: PccState, pathname: cstring) {.cdecl,
|
||||
importc: "tcc_add_include_path".}
|
||||
## add include path
|
||||
|
||||
proc addSysincludePath*(s: PccState, pathname: cstring) {.cdecl,
|
||||
importc: "tcc_add_sysinclude_path".}
|
||||
## add in system include path
|
||||
|
||||
|
||||
proc defineSymbol*(s: PccState, sym, value: cstring) {.cdecl,
|
||||
importc: "tcc_define_symbol".}
|
||||
## define preprocessor symbol 'sym'. Can put optional value
|
||||
|
||||
proc undefineSymbol*(s: PccState, sym: cstring) {.cdecl,
|
||||
importc: "tcc_undefine_symbol".}
|
||||
## undefine preprocess symbol 'sym'
|
||||
|
||||
# compiling
|
||||
|
||||
proc addFile*(s: PccState, filename: cstring): cint {.cdecl,
|
||||
importc: "tcc_add_file".}
|
||||
## add a file (either a C file, dll, an object, a library or an ld
|
||||
## script). Return -1 if error.
|
||||
|
||||
proc compileString*(s: PccState, buf: cstring): cint {.cdecl,
|
||||
importc: "tcc_compile_string".}
|
||||
## compile a string containing a C source. Return non zero if error.
|
||||
|
||||
# linking commands
|
||||
|
||||
|
||||
const
|
||||
OutputMemory*: cint = 0 ## output will be ran in memory (no
|
||||
## output file) (default)
|
||||
OutputExe*: cint = 1 ## executable file
|
||||
OutputDll*: cint = 2 ## dynamic library
|
||||
OutputObj*: cint = 3 ## object file
|
||||
OutputPreprocess*: cint = 4 ## preprocessed file (used internally)
|
||||
|
||||
OutputFormatElf*: cint = 0 ## default output format: ELF
|
||||
OutputFormatBinary*: cint = 1 ## binary image output
|
||||
OutputFormatCoff*: cint = 2 ## COFF
|
||||
|
||||
proc setOutputType*(s: PCCState, outputType: cint): cint {.cdecl,
|
||||
importc: "tcc_set_output_type".}
|
||||
## set output type. MUST BE CALLED before any compilation
|
||||
|
||||
proc addLibraryPath*(s: PccState, pathname: cstring): cint {.cdecl,
|
||||
importc: "tcc_add_library_path".}
|
||||
## equivalent to -Lpath option
|
||||
|
||||
proc addLibrary*(s: PCCState, libraryname: cstring): cint {.cdecl,
|
||||
importc: "tcc_add_library".}
|
||||
## the library name is the same as the argument of the '-l' option
|
||||
|
||||
proc addSymbol*(s: PccState, name: cstring, val: pointer): cint {.cdecl,
|
||||
importc: "tcc_add_symbol".}
|
||||
## add a symbol to the compiled program
|
||||
|
||||
proc outputFile*(s: PccState, filename: cstring): cint {.cdecl,
|
||||
importc: "tcc_output_file".}
|
||||
## output an executable, library or object file. DO NOT call
|
||||
## tcc_relocate() before.
|
||||
|
||||
proc run*(s: PccState, argc: cint, argv: cstringArray): cint {.cdecl,
|
||||
importc: "tcc_run".}
|
||||
## link and run main() function and return its value. DO NOT call
|
||||
## tcc_relocate() before.
|
||||
|
||||
proc relocate*(s: PccState, p: pointer): cint {.cdecl,
|
||||
importc: "tcc_relocate".}
|
||||
## copy code into memory passed in by the caller and do all relocations
|
||||
## (needed before using tcc_get_symbol()).
|
||||
## returns -1 on error and required size if ptr is NULL
|
||||
|
||||
proc getSymbol*(s: PccState, name: cstring): pointer {.cdecl,
|
||||
importc: "tcc_get_symbol".}
|
||||
## return symbol value or NULL if not found
|
||||
|
||||
proc setLibPath*(s: PccState, path: cstring) {.cdecl,
|
||||
importc: "tcc_set_lib_path".}
|
||||
## set CONFIG_TCCDIR at runtime
|
||||
|
||||
|
||||
48
rod/cgen.nim
48
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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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])
|
||||
|
||||
12
rod/main.nim
12
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);
|
||||
|
||||
12
rod/msgs.nim
12
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
|
||||
|
||||
@@ -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, ""))
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
new(N) # init dummy node for splay algorithm
|
||||
|
||||
@@ -1,20 +1,22 @@
|
||||
#
|
||||
#
|
||||
# Nimrod REPL
|
||||
# (c) Copyright 2010 Dominik Picheta
|
||||
#
|
||||
# See the file "copying.txt", included in this
|
||||
# distribution, for details about the copyright.
|
||||
#
|
||||
|
||||
import glib2, gtk2, gdk2, osproc, dialogs, strutils
|
||||
|
||||
type
|
||||
output = tuple[compiler, app: string]
|
||||
|
||||
proc execCode(code: string): output =
|
||||
|
||||
proc execCode(code: string): string =
|
||||
var f: TFile
|
||||
if open(f, "temp.nim", fmWrite):
|
||||
f.write(code)
|
||||
f.close()
|
||||
else:
|
||||
raise newException(EIO, "Unable to open file")
|
||||
|
||||
var compilerOutput = osproc.execProcess("nimrod c temp.nim")
|
||||
var appOutput = osproc.execProcess("temp.exe")
|
||||
return (compilerOutput, appOutput)
|
||||
raise newException(EIO, "Unable to open file")
|
||||
result = osproc.execProcess("nimrod run --verbosity:0 temp.nim")
|
||||
|
||||
var shiftPressed = False
|
||||
var w: gtk2.PWindow
|
||||
@@ -83,8 +85,8 @@ proc inputKeyReleased(widget: PWidget, event: PEventKey,
|
||||
|
||||
try:
|
||||
var r = execCode($InputText)
|
||||
set_text(OutputTextBuffer, r[0] & r[1], len(r[0] & r[1]))
|
||||
except:
|
||||
set_text(OutputTextBuffer, r, len(r))
|
||||
except EIO:
|
||||
setError("Error: Could not open file temp.nim")
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user