diff options
-rwxr-xr-x | compiler/cgen.nim | 33 | ||||
-rwxr-xr-x | compiler/pragmas.nim | 8 | ||||
-rwxr-xr-x | lib/pure/dynlib.nim | 21 | ||||
-rw-r--r-- | lib/wrappers/opengl/opengl.nim | 102 | ||||
-rwxr-xr-x | todo.txt | 1 | ||||
-rwxr-xr-x | tools/sunset.tmpl | 30 | ||||
-rwxr-xr-x | web/nimrod.ini | 7 | ||||
-rwxr-xr-x | web/ticker.txt | 36 |
8 files changed, 137 insertions, 101 deletions
diff --git a/compiler/cgen.nim b/compiler/cgen.nim index 78616ef30..7c9f2a0cd 100755 --- a/compiler/cgen.nim +++ b/compiler/cgen.nim @@ -494,6 +494,11 @@ proc libCandidates(s: string, dest: var TStringSeq) = else: add(dest, s) +proc isGetProcAddr(lib: PLib): bool = + let n = lib.path + result = n.kind in nkCallKinds and n.typ != nil and + n.typ.kind in {tyPointer, tyProc} + proc loadDynamicLib(m: BModule, lib: PLib) = assert(lib != nil) if not lib.generated: @@ -536,17 +541,35 @@ proc mangleDynLibProc(sym: PSym): PRope = proc SymInDynamicLib(m: BModule, sym: PSym) = var lib = sym.annex + let isCall = isGetProcAddr(lib) var extname = sym.loc.r - loadDynamicLib(m, lib) + if not isCall: loadDynamicLib(m, lib) if gCmd == cmdCompileToLLVM: incl(sym.loc.flags, lfIndirect) var tmp = mangleDynLibProc(sym) sym.loc.r = tmp # from now on we only need the internal name sym.typ.sym = nil # generate a new name inc(m.labels, 2) - appcg(m, m.s[cfsDynLibInit], - "$1 = ($2) #nimGetProcAddr($3, $4);$n", - [tmp, getTypeDesc(m, sym.typ), - lib.name, cstringLit(m, m.s[cfsDynLibInit], ropeToStr(extname))]) + if isCall: + let n = lib.path + var a: TLoc + initLocExpr(m.initProc, n[0], a) + var params = con(rdLoc(a), "(") + for i in 1 .. n.len-2: + initLocExpr(m.initProc, n[i], a) + params.app(rdLoc(a)) + params.app(", ") + #app(m.s[cfsVars], p.s(cpsLocals)) + #app(m.s[cfsDynLibInit], p.s(cpsInit)) + #app(m.s[cfsDynLibInit], p.s(cpsStmts)) + appcg(m, m.initProc.s(cpsStmts), + "$1 = ($2) ($3$4));$n", + [tmp, getTypeDesc(m, sym.typ), + params, cstringLit(m, m.s[cfsDynLibInit], ropeToStr(extname))]) + else: + appcg(m, m.s[cfsDynLibInit], + "$1 = ($2) #nimGetProcAddr($3, $4);$n", + [tmp, getTypeDesc(m, sym.typ), + lib.name, cstringLit(m, m.s[cfsDynLibInit], ropeToStr(extname))]) appff(m.s[cfsVars], "$2 $1;$n", "$1 = linkonce global $2 zeroinitializer$n", [sym.loc.r, getTypeDesc(m, sym.loc.t)]) diff --git a/compiler/pragmas.nim b/compiler/pragmas.nim index 14bfedd95..99c2996fa 100755 --- a/compiler/pragmas.nim +++ b/compiler/pragmas.nim @@ -201,16 +201,18 @@ proc getLib(c: PContext, kind: TLibKind, path: PNode): PLib = result.path = path Append(c.libs, result) -proc expectDynlibNode(c: PContext, n: PNode): PNode = - if n.kind != nkExprColonExpr: +proc expectDynlibNode(c: PContext, n: PNode): PNode = + if n.kind != nkExprColonExpr: LocalError(n.info, errStringLiteralExpected) # error correction: result = newEmptyStrNode(n) else: + # For the OpenGL wrapper we support: + # {.dynlib: myGetProcAddr(...).} result = c.semExpr(c, n.sons[1]) if result.kind == nkSym and result.sym.kind == skConst: result = result.sym.ast # look it up - if result.typ == nil or result.typ.kind != tyString: + if result.typ == nil or result.typ.kind notin {tyPointer, tyString, tyProc}: LocalError(n.info, errStringLiteralExpected) result = newEmptyStrNode(n) diff --git a/lib/pure/dynlib.nim b/lib/pure/dynlib.nim index 592073e3d..3ade1cbf9 100755 --- a/lib/pure/dynlib.nim +++ b/lib/pure/dynlib.nim @@ -21,19 +21,22 @@ proc LoadLib*(path: string): TLibHandle proc UnloadLib*(lib: TLibHandle) ## unloads the library `lib` -proc symAddr*(lib: TLibHandle, name: string): pointer +proc raiseInvalidLibrary*(name: cstring) {.noinline, noreturn.} = + ## raises an `EInvalidLibrary` exception. + var e: ref EInvalidLibrary + new(e) + e.msg = "could not find symbol: " & $name + raise e + +proc symAddr*(lib: TLibHandle, name: cstring): pointer ## retrieves the address of a procedure/variable from `lib`. Returns nil ## if the symbol could not be found. -proc checkedSymAddr*(lib: TLibHandle, name: string): pointer = +proc checkedSymAddr*(lib: TLibHandle, name: cstring): pointer = ## retrieves the address of a procedure/variable from `lib`. Raises ## `EInvalidLibrary` if the symbol could not be found. result = symAddr(lib, name) - if result == nil: - var e: ref EInvalidLibrary - new(e) - e.msg = "could not find symbol: " & name - raise e + if result == nil: raiseInvalidLibrary(name) when defined(posix): # @@ -55,7 +58,7 @@ when defined(posix): proc LoadLib(path: string): TLibHandle = return dlopen(path, RTLD_NOW) proc UnloadLib(lib: TLibHandle) = dlclose(lib) - proc symAddr(lib: TLibHandle, name: string): pointer = + proc symAddr(lib: TLibHandle, name: cstring): pointer = return dlsym(lib, name) elif defined(windows) or defined(dos): @@ -77,7 +80,7 @@ elif defined(windows) or defined(dos): result = cast[TLibHandle](winLoadLibrary(path)) proc UnloadLib(lib: TLibHandle) = FreeLibrary(cast[THINSTANCE](lib)) - proc symAddr(lib: TLibHandle, name: string): pointer = + proc symAddr(lib: TLibHandle, name: cstring): pointer = result = GetProcAddress(cast[THINSTANCE](lib), name) else: diff --git a/lib/wrappers/opengl/opengl.nim b/lib/wrappers/opengl/opengl.nim index cdec0b0f7..444f23fc1 100644 --- a/lib/wrappers/opengl/opengl.nim +++ b/lib/wrappers/opengl/opengl.nim @@ -8,8 +8,27 @@ # ## This module is a wrapper around `opengl`:idx:. If you define the symbol -## ``useGlew`` this wrapper does not use Nimrod's ``dynlib`` mechanism (which -## ends up calling ``dlsym`` or ``GetProcAddress``), but `glew`:idx: instead. +## ``useGlew`` this wrapper does not use Nimrod's ``dynlib`` mechanism, +## but `glew`:idx: instead. However, this shouldn't be necessary anymore; even +## extension loading for the different operating systems is handled here. + +when defined(linux): + import X, XLib, XUtil +elif defined(windows): + import winlean, os + +when defined(windows): + const + ogldll* = "OpenGL32.dll" + gludll* = "GLU32.dll" +elif defined(macosx): + const + ogldll* = "libGL.dylib" + gludll* = "libGLU.dylib" +else: + const + ogldll* = "libGL.so.1" + gludll* = "libGLU.so.1" when defined(useGlew): {.pragma: ogl, header: "<GL/glew.h>".} @@ -17,11 +36,51 @@ when defined(useGlew): {.pragma: wgl, header: "<GL/wglew.h>".} {.pragma: glu, dynlib: gludll.} else: - {.pragma: ogl, dynlib: ogldll.} - {.pragma: oglx, dynlib: ogldll.} - {.pragma: wgl, dynlib: ogldll.} - {.pragma: glu, dynlib: gludll.} - + # quite complex ... thanks to extension support for various platforms: + import dynlib + + let oglHandle = LoadLib(ogldll) + if isNil(oglHandle): quit("could not load: " & ogldll) + + when defined(windows): + var wglGetProcAddress = cast[proc (s: cstring): pointer {.stdcall.}]( + symAddr(oglHandle, "wglGetProcAddress")) + elif defined(linux): + var glXGetProcAddress = cast[proc (s: cstring): pointer {.cdecl.}]( + symAddr(oglHandle, "glXGetProcAddress")) + var glXGetProcAddressARB = cast[proc (s: cstring): pointer {.cdecl.}]( + symAddr(oglHandle, "glXGetProcAddressARB")) + + proc glGetProc(h: TLibHandle; procName: cstring): pointer = + when defined(windows): + result = symAddr(h, procname) + if result != nil: return + if not isNil(wglGetProcAddress): result = wglGetProcAddress(ProcName) + elif defined(linux): + if not isNil(glXGetProcAddress): result = glXGetProcAddress(ProcName) + if result != nil: return + if not isNil(glXGetProcAddressARB): + result = glXGetProcAddressARB(ProcName) + if result != nil: return + result = symAddr(h, procname) + else: + result = symAddr(h, procName) + if result == nil: raiseInvalidLibrary(procName) + + var gluHandle: TLibHandle + + proc gluGetProc(procname: cstring): pointer = + if gluHandle == nil: + gluHandle = LoadLib(gludll) + if gluHandle == nil: quit("could not load: " & gludll) + result = glGetProc(gluHandle, procname) + + # undocumented 'dynlib' feature: the empty string literal is replaced by + # the imported proc name: + {.pragma: ogl, dynlib: glGetProc(oglHandle, "").} + {.pragma: oglx, dynlib: glGetProc(oglHandle, "").} + {.pragma: wgl, dynlib: glGetProc(oglHandle, "").} + {.pragma: glu, dynlib: gluGetProc("").} #============================================================================== # @@ -398,27 +457,6 @@ else: {.deadCodeElim: on.} -when defined(LINUX): - import - X, XLib, XUtil - -when defined(windows): - import - winlean, os - -when defined(windows): - const - ogldll* = "OpenGL32.dll" - gludll* = "GLU32.dll" -elif defined(macosx): - const - ogldll* = "libGL.dylib" - gludll* = "libGLU.dylib" -else: - const - ogldll* = "libGL.so.1" - gludll* = "libGLU.so.1" - type PPointer* = ptr Pointer GLenum* = int @@ -9396,10 +9434,12 @@ when defined(LINUX): stdcall, importc, oglx.} proc glXGetSelectedEvent*(dpy: PDisplay, draw: GLXDrawable, event_mask: PGLuint){.stdcall, importc, oglx.} - # GLX_VERSION_1_4 - proc glXGetProcAddress*(name: cstring): pointer{.stdcall, importc, oglx.} + # GLX_VERSION_1_4 + when not defined(glXGetProcAddress): + proc glXGetProcAddress*(name: cstring): pointer{.stdcall, importc, oglx.} # GLX_ARB_get_proc_address - proc glXGetProcAddressARB*(name: cstring): pointer{.stdcall, importc, oglx.} + when not defined(glXGetProcAddressARB): + proc glXGetProcAddressARB*(name: cstring): pointer{.stdcall, importc, oglx.} # GLX_ARB_create_context proc glXCreateContextAttribsARB*(dpy: PDisplay, config: GLXFBConfig, share_context: GLXContext, direct: GLboolean, diff --git a/todo.txt b/todo.txt index f2ff040d5..1b601bef6 100755 --- a/todo.txt +++ b/todo.txt @@ -1,6 +1,7 @@ version 0.9.2 ============= +- fix broken expr/stmt handling for proc bodies - make 'bind' default for templates and introduce 'mixin' - implicit deref for parameter matching; overloading based on 'var T' - optimize genericAssign in the code generator diff --git a/tools/sunset.tmpl b/tools/sunset.tmpl index c8e06c659..16a6f4026 100755 --- a/tools/sunset.tmpl +++ b/tools/sunset.tmpl @@ -34,20 +34,10 @@ </ul> </div> <div id="column1"> -# if len(c.ticker) > 0: - <div class="sidebaritem"> - <div class="sbihead"> - <h1>latest news</h1> - </div> - <div class="sbicontent"> - $c.ticker - </div> - </div> -# end if # if len(c.links) > 0: <div class="sidebaritem"> <div class="sbihead"> - <h1>additional links</h1> + <h1>projects</h1> </div> <div class="sbilinks"> <!-- **** INSERT ADDITIONAL LINKS HERE **** --> @@ -59,15 +49,27 @@ </div> </div> # end if +# if len(c.ticker) > 0: + <div class="sidebaritem"> + <div class="sbihead"> + <h1>latest news</h1> + </div> + <div class="sbicontent"> + $c.ticker + </div> + </div> +# end if </div> <div id="column2"> $content </div> </div> <div id="footer"> - copyright © 2012 $c.authors | Last update: ${getDateStr()} - | <a class="reference" href="http://validator.w3.org/check?uri=referer">XHTML 1.1</a> - | <a class="reference" href="http://jigsaw.w3.org/css-validator/check/referer">CSS</a> + © 2012 $c.authors | Last update: ${getDateStr()} + <!-- | <iframe style="border: 0; margin: 0; padding: 0;" + src="https://www.gittip.com/Araq/widget.html" + width="48pt" height="15pt"></iframe> --> + | <a class="reference" href="http://www.dcarter.co.uk">design by dcarter</a> </div> </div> diff --git a/web/nimrod.ini b/web/nimrod.ini index 4951cd578..dc636309a 100755 --- a/web/nimrod.ini +++ b/web/nimrod.ini @@ -2,11 +2,12 @@ Name: "Nimrod" Title: "Nimrod Programming Language" Logo: "efficient, expressive, elegant" -Authors: "Andreas Rumpf" +Authors: "Andreas Rumpf and contributors" [Links] -GCC: "http://gcc.gnu.org" -LLVM: "http://llvm.org" +FORUM: "http://forum.nimrod-code.org" +APORIA: "https://github.com/nimrod-code/Aporia" +NIMBUILD: "http://build.nimrod-code.org" [Tabs] # Menu entry: filename diff --git a/web/ticker.txt b/web/ticker.txt index 2e0e5722b..6b247c735 100755 --- a/web/ticker.txt +++ b/web/ticker.txt @@ -14,39 +14,3 @@ | `2010-03-14`:newsdate: | Nimrod version 0.8.8 has been released! -| `2009-12-21`:newsdate: -| Nimrod version 0.8.6 has been released! - -| `2009-10-21`:newsdate: -| Nimrod version 0.8.2 has been released! - -| `2009-09-12`:newsdate: -| Nimrod version 0.8.0 has been released! - -| `2009-06-08`:newsdate: -| Nimrod version 0.7.10 has been released! - -| `2009-05-08`:newsdate: -| Nimrod version 0.7.8 has been released! - -| `2009-04-22`:newsdate: -| Nimrod version 0.7.6 has been released! - -| `2009-01-22`:newsdate: -| Forum added! - -| `2009-01-07`:newsdate: -| Nimrod version 0.7.4 has been released! - -| `2008-12-12`:newsdate: -| Nimrod version 0.7.2 has been released! - -| `2008-11-16`:newsdate: -| Nimrod version 0.7.0 has been released! - -| `2008-08-22`:newsdate: -| Nimrod version 0.6.0 has been released! - -| `2008-06-22`:newsdate: -| This page is finally online! - |