version 0.8.8
This commit is contained in:
parent
3dafd6856b
commit
7bf98411b6
52 changed files with 15732 additions and 6193 deletions
|
|
@ -138,7 +138,7 @@ pre, span.tok {
|
||||||
border-width: 1px 1px 1px 2px;
|
border-width: 1px 1px 1px 2px;
|
||||||
color: black;
|
color: black;
|
||||||
line-spacing: 110%;
|
line-spacing: 110%;
|
||||||
padding: 5px;
|
padding: 2px;
|
||||||
}
|
}
|
||||||
|
|
||||||
span.red {
|
span.red {
|
||||||
|
|
@ -264,8 +264,10 @@ table.docutils td, table.docutils th,
|
||||||
table.docinfo td, table.docinfo th {padding-left: 0.5em;padding-right: 0.5em;
|
table.docinfo td, table.docinfo th {padding-left: 0.5em;padding-right: 0.5em;
|
||||||
vertical-align: top;}
|
vertical-align: top;}
|
||||||
|
|
||||||
table.docutils td, table.docutils th { border-bottom:1px solid #9D9D9D; color: #4d4d4d}
|
table.docutils td, table.docutils th { border-bottom:1px solid #9D9D9D; }
|
||||||
table.docutils td:hover, table.docinfo td:hover {color: #000000}
|
/* color: #4d4d4d} */
|
||||||
|
|
||||||
|
/* table.docutils td:hover, table.docinfo td:hover {color: #000000} */
|
||||||
|
|
||||||
|
|
||||||
table.docutils th.field-name, table.docinfo th.docinfo-name {
|
table.docutils th.field-name, table.docinfo th.docinfo-name {
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,7 @@ path="$lib/wrappers/zip"
|
||||||
path="$lib/windows"
|
path="$lib/windows"
|
||||||
path="$lib/posix"
|
path="$lib/posix"
|
||||||
path="$lib/ecmas"
|
path="$lib/ecmas"
|
||||||
|
path="$lib/pure/unidecode"
|
||||||
|
|
||||||
@if release or quick:
|
@if release or quick:
|
||||||
obj_checks:off
|
obj_checks:off
|
||||||
|
|
|
||||||
|
|
@ -43,7 +43,7 @@ String handling
|
||||||
string into uppercase, splitting a string into substrings, searching for
|
string into uppercase, splitting a string into substrings, searching for
|
||||||
substrings, replacing substrings.
|
substrings, replacing substrings.
|
||||||
|
|
||||||
* `parseutils <parseutils.html>`
|
* `parseutils <parseutils.html>`_
|
||||||
This module contains helpers for parsing tokens, numbers, identifiers, etc.
|
This module contains helpers for parsing tokens, numbers, identifiers, etc.
|
||||||
|
|
||||||
* `strtabs <strtabs.html>`_
|
* `strtabs <strtabs.html>`_
|
||||||
|
|
@ -119,7 +119,7 @@ Internet Protocols and Support
|
||||||
* `cgi <cgi.html>`_
|
* `cgi <cgi.html>`_
|
||||||
This module implements helpers for CGI applictions.
|
This module implements helpers for CGI applictions.
|
||||||
|
|
||||||
* `sockets <sockets.html>`
|
* `sockets <sockets.html>`_
|
||||||
This module implements a simple portable type-safe sockets layer.
|
This module implements a simple portable type-safe sockets layer.
|
||||||
|
|
||||||
* `browsers <browsers.html>`_
|
* `browsers <browsers.html>`_
|
||||||
|
|
@ -208,7 +208,7 @@ Multimedia support
|
||||||
Impure libraries
|
Impure libraries
|
||||||
================
|
================
|
||||||
|
|
||||||
* `graphics <graphics>`_
|
* `graphics <graphics.html>`_
|
||||||
This module implements graphical output for Nimrod; the current
|
This module implements graphical output for Nimrod; the current
|
||||||
implementation uses SDL but the interface is meant to support multiple
|
implementation uses SDL but the interface is meant to support multiple
|
||||||
backends some day.
|
backends some day.
|
||||||
|
|
|
||||||
|
|
@ -441,7 +441,7 @@ Ordinal types
|
||||||
- Ordinal values have a largest possible value. Trying to count further
|
- Ordinal values have a largest possible value. Trying to count further
|
||||||
than the largest value gives a checked runtime or static error.
|
than the largest value gives a checked runtime or static error.
|
||||||
|
|
||||||
Integers, bool, characters and enumeration types (and subrange of these
|
Integers, bool, characters and enumeration types (and subranges of these
|
||||||
types) belong to ordinal types.
|
types) belong to ordinal types.
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -451,8 +451,8 @@ These integer types are pre-defined:
|
||||||
|
|
||||||
``int``
|
``int``
|
||||||
the generic signed integer type; its size is platform dependent
|
the generic signed integer type; its size is platform dependent
|
||||||
(the compiler chooses the processor's fastest integer type)
|
(the compiler chooses the processor's fastest integer type).
|
||||||
this type should be used in general. An integer literal that has no type
|
This type should be used in general. An integer literal that has no type
|
||||||
suffix is of this type.
|
suffix is of this type.
|
||||||
|
|
||||||
intXX
|
intXX
|
||||||
|
|
@ -502,8 +502,8 @@ The following floating point types are pre-defined:
|
||||||
|
|
||||||
``float``
|
``float``
|
||||||
the generic floating point type; its size is platform dependent
|
the generic floating point type; its size is platform dependent
|
||||||
(the compiler chooses the processor's fastest floating point type)
|
(the compiler chooses the processor's fastest floating point type).
|
||||||
this type should be used in general
|
This type should be used in general.
|
||||||
|
|
||||||
floatXX
|
floatXX
|
||||||
an implementation may define additional floating point types of XX bits using
|
an implementation may define additional floating point types of XX bits using
|
||||||
|
|
@ -2193,6 +2193,8 @@ special ``:`` syntax:
|
||||||
In the example the two ``writeln`` statements are bound to the ``actions``
|
In the example the two ``writeln`` statements are bound to the ``actions``
|
||||||
parameter.
|
parameter.
|
||||||
|
|
||||||
|
**Note:** Symbol binding rules in templates might change!
|
||||||
|
|
||||||
Symbol binding within templates happens after template instantation:
|
Symbol binding within templates happens after template instantation:
|
||||||
|
|
||||||
.. code-block:: nimrod
|
.. code-block:: nimrod
|
||||||
|
|
@ -2476,7 +2478,7 @@ or ``ref T`` or ``ptr T`` this means no locations are modified. It is a static
|
||||||
error to mark a proc/iterator to have no side effect if the compiler cannot
|
error to mark a proc/iterator to have no side effect if the compiler cannot
|
||||||
verify this.
|
verify this.
|
||||||
|
|
||||||
**Possible future**: ``func`` may become a keyword and syntactic sugar for a
|
**Future directions**: ``func`` may become a keyword and syntactic sugar for a
|
||||||
proc with no side effects:
|
proc with no side effects:
|
||||||
|
|
||||||
.. code-block:: nimrod
|
.. code-block:: nimrod
|
||||||
|
|
@ -2521,7 +2523,7 @@ information that this cannot happen to the GC. If the programmer uses the
|
||||||
``acyclic`` pragma for data types that are in reality cyclic, the GC may leak
|
``acyclic`` pragma for data types that are in reality cyclic, the GC may leak
|
||||||
memory, but nothing worse happens.
|
memory, but nothing worse happens.
|
||||||
|
|
||||||
**Possible future**: The ``acyclic`` pragma may become a property of a
|
**Future directions**: The ``acyclic`` pragma may become a property of a
|
||||||
``ref`` type:
|
``ref`` type:
|
||||||
|
|
||||||
.. code-block:: nimrod
|
.. code-block:: nimrod
|
||||||
|
|
@ -2544,8 +2546,8 @@ The `pure`:idx: pragma serves two completely different purposes:
|
||||||
1) To mark a procedure that Nimrod should not generate any exit statements like
|
1) To mark a procedure that Nimrod should not generate any exit statements like
|
||||||
``return result;`` in the generated code. This is useful for procs that only
|
``return result;`` in the generated code. This is useful for procs that only
|
||||||
consist of an assembler statement.
|
consist of an assembler statement.
|
||||||
2) To mark an object type that Nimrod should omit its type field. This is
|
2) To mark an object type so that its type field should be omitted. This is
|
||||||
necessary for compatibility with other compiled languages.
|
necessary for binary compatibility with other compiled languages.
|
||||||
|
|
||||||
|
|
||||||
error pragma
|
error pragma
|
||||||
|
|
|
||||||
1567
doc/theindex.txt
1567
doc/theindex.txt
File diff suppressed because it is too large
Load diff
25
examples/parsecfgex.nim
Executable file
25
examples/parsecfgex.nim
Executable file
|
|
@ -0,0 +1,25 @@
|
||||||
|
|
||||||
|
import
|
||||||
|
os, parsecfg, strutils, streams
|
||||||
|
|
||||||
|
var f = newFileStream(paramStr(1), fmRead)
|
||||||
|
if f != nil:
|
||||||
|
var p: TCfgParser
|
||||||
|
open(p, f, paramStr(1))
|
||||||
|
while true:
|
||||||
|
var e = next(p)
|
||||||
|
case e.kind
|
||||||
|
of cfgEof:
|
||||||
|
echo("EOF!")
|
||||||
|
break
|
||||||
|
of cfgSectionStart: ## a ``[section]`` has been parsed
|
||||||
|
echo("new section: " & e.section)
|
||||||
|
of cfgKeyValuePair:
|
||||||
|
echo("key-value-pair: " & e.key & ": " & e.value)
|
||||||
|
of cfgOption:
|
||||||
|
echo("command: " & e.key & ": " & e.value)
|
||||||
|
of cfgError:
|
||||||
|
echo(e.msg)
|
||||||
|
close(p)
|
||||||
|
else:
|
||||||
|
echo("cannot open: " & paramStr(1))
|
||||||
|
|
@ -11,9 +11,9 @@
|
||||||
## implementation uses SDL but the interface is meant to support multiple
|
## implementation uses SDL but the interface is meant to support multiple
|
||||||
## backends some day.
|
## backends some day.
|
||||||
|
|
||||||
import colors
|
import colors, math
|
||||||
from sdl import PSurface # Bug
|
from sdl import PSurface # Bug
|
||||||
from sdl_ttf import OpenFont
|
from sdl_ttf import OpenFont, closeFont
|
||||||
|
|
||||||
type
|
type
|
||||||
TRect* = tuple[x, y, width, height: int]
|
TRect* = tuple[x, y, width, height: int]
|
||||||
|
|
@ -24,7 +24,22 @@ type
|
||||||
w, h: int
|
w, h: int
|
||||||
s: sdl.PSurface
|
s: sdl.PSurface
|
||||||
|
|
||||||
ESDLError = object of EBase
|
EGraphics* = object of EBase
|
||||||
|
|
||||||
|
TFont {.pure, final.} = object
|
||||||
|
f: sdl_ttf.PFont
|
||||||
|
color: SDL.TColor
|
||||||
|
PFont* = ref TFont ## represents a font
|
||||||
|
|
||||||
|
proc toSdlColor(c: TColor): Sdl.TColor =
|
||||||
|
# Convert colors.TColor to SDL.TColor
|
||||||
|
var x = c.extractRGB
|
||||||
|
result.r = toU8(x.r)
|
||||||
|
result.g = toU8(x.g)
|
||||||
|
result.b = toU8(x.b)
|
||||||
|
|
||||||
|
proc raiseEGraphics =
|
||||||
|
raise newException(EGraphics, $SDL.GetError())
|
||||||
|
|
||||||
proc surfaceFinalizer(s: PSurface) = sdl.freeSurface(s.s)
|
proc surfaceFinalizer(s: PSurface) = sdl.freeSurface(s.s)
|
||||||
|
|
||||||
|
|
@ -38,6 +53,24 @@ proc newSurface*(width, height: int): PSurface =
|
||||||
|
|
||||||
assert(not sdl.MustLock(result.s))
|
assert(not sdl.MustLock(result.s))
|
||||||
|
|
||||||
|
proc fontFinalizer(f: PFont) = closeFont(f.f)
|
||||||
|
|
||||||
|
proc newFont*(name = "VeraMono.ttf", size = 9, color = colBlack): PFont =
|
||||||
|
## Creates a new font object. Raises ``EIO`` if the font cannot be loaded.
|
||||||
|
new(result, fontFinalizer)
|
||||||
|
result.f = OpenFont(name, size)
|
||||||
|
if result.f == nil:
|
||||||
|
raise newException(EIO, "Could not open font file: " & name)
|
||||||
|
result.color = toSdlColor(color)
|
||||||
|
|
||||||
|
var
|
||||||
|
defaultFont*: PFont ## default font that is used; this needs to initialized
|
||||||
|
## by the client!
|
||||||
|
|
||||||
|
proc initDefaultFont*(name = "VeraMono.ttf", size = 9, color = colBlack) =
|
||||||
|
## initializes the `defaultFont` var.
|
||||||
|
defaultFont = newFont(name, size, color)
|
||||||
|
|
||||||
proc newScreenSurface(width, height: int): PSurface =
|
proc newScreenSurface(width, height: int): PSurface =
|
||||||
## Creates a new screen surface
|
## Creates a new screen surface
|
||||||
new(result, surfaceFinalizer)
|
new(result, surfaceFinalizer)
|
||||||
|
|
@ -45,12 +78,6 @@ proc newScreenSurface(width, height: int): PSurface =
|
||||||
result.h = height
|
result.h = height
|
||||||
result.s = SDL.SetVideoMode(width, height, 0, 0)
|
result.s = SDL.SetVideoMode(width, height, 0, 0)
|
||||||
|
|
||||||
template withEvents(surf: PSurface, event: expr, actions: stmt): stmt =
|
|
||||||
while True:
|
|
||||||
var event: SDL.TEvent
|
|
||||||
if SDL.PollEvent(addr(event)) == 1:
|
|
||||||
actions
|
|
||||||
|
|
||||||
proc writeToBMP*(sur: PSurface, filename: string) =
|
proc writeToBMP*(sur: PSurface, filename: string) =
|
||||||
## Saves the contents of the surface `sur` to the file `filename` as a
|
## Saves the contents of the surface `sur` to the file `filename` as a
|
||||||
## BMP file.
|
## BMP file.
|
||||||
|
|
@ -70,28 +97,37 @@ template getPix(video, pitch, x, y: expr): expr =
|
||||||
const
|
const
|
||||||
ColSize = 4
|
ColSize = 4
|
||||||
|
|
||||||
proc getPixel(sur: PSurface, x, y: Natural): colors.TColor =
|
proc getPixel(sur: PSurface, x, y: Natural): colors.TColor {.inline.} =
|
||||||
|
assert x <% sur.w
|
||||||
|
assert y <% sur.h
|
||||||
result = getPix(cast[PPixels](sur.s.pixels), sur.s.pitch div ColSize, x, y)
|
result = getPix(cast[PPixels](sur.s.pixels), sur.s.pitch div ColSize, x, y)
|
||||||
|
|
||||||
proc setPixel(sur: PSurface, x, y: Natural, col: colors.TColor) =
|
proc setPixel(sur: PSurface, x, y: Natural, col: colors.TColor) {.inline.} =
|
||||||
|
assert x <% sur.w
|
||||||
|
assert y <% sur.h
|
||||||
var pixs = cast[PPixels](sur.s.pixels)
|
var pixs = cast[PPixels](sur.s.pixels)
|
||||||
#pixs[y * (sur.s.pitch div colSize) + x] = int(col)
|
#pixs[y * (sur.s.pitch div colSize) + x] = int(col)
|
||||||
setPix(pixs, sur.s.pitch div ColSize, x, y, col)
|
setPix(pixs, sur.s.pitch div ColSize, x, y, col)
|
||||||
|
|
||||||
proc `[]`*(sur: PSurface, p: TPoint): TColor =
|
proc `[]`*(sur: PSurface, p: TPoint): TColor =
|
||||||
|
## get pixel at position `p`. No range checking is done!
|
||||||
result = getPixel(sur, p.x, p.y)
|
result = getPixel(sur, p.x, p.y)
|
||||||
|
|
||||||
#proc `[,]`*(sur: PSurface, x, y: int): TColor =
|
proc `[,]`*(sur: PSurface, x, y: int): TColor =
|
||||||
# result = setPixel(sur, x, y)
|
## get pixel at position ``(x, y)``. No range checking is done!
|
||||||
|
result = getPixel(sur, x, y)
|
||||||
|
|
||||||
proc `[]=`*(sur: PSurface, p: TPoint, col: TColor) =
|
proc `[]=`*(sur: PSurface, p: TPoint, col: TColor) =
|
||||||
|
## set the pixel at position `p`. No range checking is done!
|
||||||
setPixel(sur, p.x, p.y, col)
|
setPixel(sur, p.x, p.y, col)
|
||||||
|
|
||||||
#proc `[,]=`*(sur: PSurface, x, y: int, col: TColor) =
|
proc `[,]=`*(sur: PSurface, x, y: int, col: TColor) =
|
||||||
# setPixel(sur, x, y, col)
|
## set the pixel at position ``(x, y)``. No range checking is done!
|
||||||
|
setPixel(sur, x, y, col)
|
||||||
|
|
||||||
proc blitSurface*(destSurf: PSurface, destRect: TRect, srcSurf: PSurface, srcRect: TRect) =
|
proc blit*(destSurf: PSurface, destRect: TRect, srcSurf: PSurface,
|
||||||
## Merges ``srcSurf`` into ``destSurf``
|
srcRect: TRect) =
|
||||||
|
## Copies ``srcSurf`` into ``destSurf``
|
||||||
var destTRect, srcTRect: SDL.TRect
|
var destTRect, srcTRect: SDL.TRect
|
||||||
|
|
||||||
destTRect.x = int16(destRect.x)
|
destTRect.x = int16(destRect.x)
|
||||||
|
|
@ -105,72 +141,36 @@ proc blitSurface*(destSurf: PSurface, destRect: TRect, srcSurf: PSurface, srcRec
|
||||||
srcTRect.h = int16(srcRect.height)
|
srcTRect.h = int16(srcRect.height)
|
||||||
|
|
||||||
if SDL.blitSurface(srcSurf.s, addr(srcTRect), destSurf.s, addr(destTRect)) != 0:
|
if SDL.blitSurface(srcSurf.s, addr(srcTRect), destSurf.s, addr(destTRect)) != 0:
|
||||||
raise newException(ESDLError, $SDL.GetError())
|
raiseEGraphics()
|
||||||
|
|
||||||
proc textBounds*(font: string, fontSize: int, text: string): tuple[width, height: int] =
|
|
||||||
var fontFile = OpenFont(font, fontSize) # Open the font file
|
|
||||||
if fontFile == nil: raise newException(ESDLError, "Could not open font file")
|
|
||||||
|
|
||||||
|
proc textBounds*(text: string, font = defaultFont): tuple[width, height: int] =
|
||||||
var w, h: cint
|
var w, h: cint
|
||||||
if sdl_ttf.SizeUTF8(fontFile, text, w, h) < 0:
|
if sdl_ttf.SizeUTF8(font.f, text, w, h) < 0: raiseEGraphics()
|
||||||
raise newException(ESDLError, $SDL.GetError())
|
result.width = int(w)
|
||||||
return (int(w), int(h))
|
result.height = int(h)
|
||||||
|
|
||||||
proc drawText*(sur: PSurface, p: TPoint, font: string, text: string,
|
|
||||||
fg: TColor = colBlack, fontSize: int = 9) =
|
|
||||||
## Draws text with a transparent background, at location ``p``.
|
|
||||||
## ``font`` specifies the path to the ttf file,
|
|
||||||
## ``fontSize`` specifies the font size in pt, and ``fg``
|
|
||||||
## specifies the foreground color.
|
|
||||||
var fontFile = OpenFont(font, fontSize) # Open the font file
|
|
||||||
if fontFile == nil: raise newException(ESDLError, "Could not open font file")
|
|
||||||
|
|
||||||
|
proc drawText*(sur: PSurface, p: TPoint, text: string, font = defaultFont) =
|
||||||
|
## Draws text with a transparent background, at location ``p`` with the given
|
||||||
|
## font.
|
||||||
var textSur: PSurface # This surface will have the text drawn on it
|
var textSur: PSurface # This surface will have the text drawn on it
|
||||||
new(textSur, surfaceFinalizer)
|
new(textSur, surfaceFinalizer)
|
||||||
|
|
||||||
var RGBfg = fg.extractRGB
|
|
||||||
|
|
||||||
# Convert colors.TColor to SDL.TColor
|
|
||||||
var SDLfg: SDL.TColor
|
|
||||||
SDLfg.r = toU8(RGBfg.r)
|
|
||||||
SDLfg.g = toU8(RGBfg.g)
|
|
||||||
SDLfg.b = toU8(RGBfg.b)
|
|
||||||
|
|
||||||
# Render the text
|
# Render the text
|
||||||
textSur.s = sdl_ttf.RenderTextBlended(fontFile, text, SDLfg)
|
textSur.s = sdl_ttf.RenderTextBlended(font.f, text, font.color)
|
||||||
# Merge the text surface with sur
|
# Merge the text surface with sur
|
||||||
sur.blitSurface((p.x, p.y, sur.w, sur.h), textSur, (0, 0, sur.w, sur.h))
|
sur.blit((p.x, p.y, sur.w, sur.h), textSur, (0, 0, sur.w, sur.h))
|
||||||
# Free the surface
|
# Free the surface
|
||||||
SDL.FreeSurface(sur.s)
|
SDL.FreeSurface(sur.s)
|
||||||
|
|
||||||
proc drawText*(sur: PSurface, p: TPoint, font: string, text: string,
|
proc drawText*(sur: PSurface, p: TPoint, text: string,
|
||||||
bg: TColor, fg: TColor = colBlack, fontSize: int = 9) =
|
bg: TColor, font = defaultFont) =
|
||||||
## Draws text, at location ``p``, ``font`` specifies the path to
|
## Draws text, at location ``p`` with font ``font``. ``bg``
|
||||||
## the ttf file, ``fontSize`` specifies the font size in pt, and ``fg``
|
## is the background color.
|
||||||
## and ``bg`` specify the foreground and background colors.
|
|
||||||
var fontFile = OpenFont(font, fontSize) # Open the font file
|
|
||||||
if fontFile == nil: raise newException(ESDLError, "Could not open font file")
|
|
||||||
|
|
||||||
var textSur: PSurface # This surface will have the text drawn on it
|
var textSur: PSurface # This surface will have the text drawn on it
|
||||||
new(textSur, surfaceFinalizer)
|
new(textSur, surfaceFinalizer)
|
||||||
|
textSur.s = sdl_ttf.RenderTextShaded(font.f, text, font.color, toSdlColor(bg))
|
||||||
var RGBfg = fg.extractRGB
|
|
||||||
var RGBbg = bg.extractRGB
|
|
||||||
|
|
||||||
# Convert colors.TColor to SDL.TColor
|
|
||||||
var SDLfg: SDL.TColor
|
|
||||||
SDLfg.r = toU8(RGBfg.r)
|
|
||||||
SDLfg.g = toU8(RGBfg.g)
|
|
||||||
SDLfg.b = toU8(RGBfg.b)
|
|
||||||
var SDLbg: SDL.TColor
|
|
||||||
SDLbg.r = toU8(RGBbg.r)
|
|
||||||
SDLbg.g = toU8(RGBbg.g)
|
|
||||||
SDLbg.b = toU8(RGBbg.b)
|
|
||||||
|
|
||||||
# Render the text
|
|
||||||
textSur.s = sdl_ttf.RenderTextShaded(fontFile, text, SDLfg, SDLbg)
|
|
||||||
# Merge the text surface with sur
|
# Merge the text surface with sur
|
||||||
sur.blitSurface((p.x, p.y, sur.w, sur.h), textSur, (0, 0, sur.w, sur.h))
|
sur.blit((p.x, p.y, sur.w, sur.h), textSur, (0, 0, sur.w, sur.h))
|
||||||
# Free the surface
|
# Free the surface
|
||||||
SDL.FreeSurface(sur.s)
|
SDL.FreeSurface(sur.s)
|
||||||
|
|
||||||
|
|
@ -185,15 +185,21 @@ proc drawCircle*(sur: PSurface, p: TPoint, r: Natural, color: TColor) =
|
||||||
var x = p.x
|
var x = p.x
|
||||||
var y = p.y
|
var y = p.y
|
||||||
while px <= py + 1:
|
while px <= py + 1:
|
||||||
setPix(video, pitch, x + px, y + py, color)
|
if x+px <% sur.w:
|
||||||
setPix(video, pitch, x + px, y - py, color)
|
if y+py <% sur.h: setPix(video, pitch, x+px, y+py, color)
|
||||||
setPix(video, pitch, x - px, y + py, color)
|
if y-py <% sur.h: setPix(video, pitch, x+px, y-py, color)
|
||||||
setPix(video, pitch, x - px, y - py, color)
|
|
||||||
|
|
||||||
setPix(video, pitch, x + py, y + px, color)
|
if x-px <% sur.w:
|
||||||
setPix(video, pitch, x + py, y - px, color)
|
if y+py <% sur.h: setPix(video, pitch, x-px, y+py, color)
|
||||||
setPix(video, pitch, x - py, y + px, color)
|
if y-py <% sur.h: setPix(video, pitch, x-px, y-py, color)
|
||||||
setPix(video, pitch, x - py, y - px, color)
|
|
||||||
|
if x+py <% sur.w:
|
||||||
|
if y+px <% sur.h: setPix(video, pitch, x+py, y+px, color)
|
||||||
|
if y-px <% sur.h: setPix(video, pitch, x+py, y-px, color)
|
||||||
|
|
||||||
|
if x-py <% sur.w:
|
||||||
|
if y+px <% sur.h: setPix(video, pitch, x-py, y+px, color)
|
||||||
|
if y-px <% sur.h: setPix(video, pitch, x-py, y-px, color)
|
||||||
|
|
||||||
if a < 0:
|
if a < 0:
|
||||||
a = a + (2 * px + 3)
|
a = a + (2 * px + 3)
|
||||||
|
|
@ -202,16 +208,22 @@ proc drawCircle*(sur: PSurface, p: TPoint, r: Natural, color: TColor) =
|
||||||
py = py - 1
|
py = py - 1
|
||||||
px = px + 1
|
px = px + 1
|
||||||
|
|
||||||
|
proc `>-<`(val: int, s: PSurface): int {.inline.} =
|
||||||
|
return if val < 0: 0 elif val >= s.w: s.w-1 else: val
|
||||||
|
|
||||||
|
proc `>|<`(val: int, s: PSurface): int {.inline.} =
|
||||||
|
return if val < 0: 0 elif val >= s.h: s.h-1 else: val
|
||||||
|
|
||||||
proc drawLine*(sur: PSurface, p1, p2: TPoint, color: TColor) =
|
proc drawLine*(sur: PSurface, p1, p2: TPoint, color: TColor) =
|
||||||
## draws a line between the two points `p1` and `p2` with the given color
|
## draws a line between the two points `p1` and `p2` with the given color
|
||||||
## onto the surface `sur`.
|
## onto the surface `sur`.
|
||||||
var stepx, stepy: int = 0
|
var stepx, stepy: int = 0
|
||||||
var x0: int = p1.x
|
var x0 = p1.x >-< sur
|
||||||
var x1: int = p2.x
|
var x1 = p2.x >-< sur
|
||||||
var y0: int = p1.y
|
var y0 = p1.y >|< sur
|
||||||
var y1: int = p2.y
|
var y1 = p2.y >|< sur
|
||||||
var dy: int = y1 - y0
|
var dy = y1 - y0
|
||||||
var dx: int = x1 - x0
|
var dx = x1 - x0
|
||||||
if dy < 0:
|
if dy < 0:
|
||||||
dy = -dy
|
dy = -dy
|
||||||
stepy = -1
|
stepy = -1
|
||||||
|
|
@ -247,7 +259,7 @@ proc drawLine*(sur: PSurface, p1, p2: TPoint, color: TColor) =
|
||||||
setPix(video, pitch, x0, y0, color)
|
setPix(video, pitch, x0, y0, color)
|
||||||
|
|
||||||
proc drawHorLine*(sur: PSurface, x, y, w: Natural, Color: TColor) =
|
proc drawHorLine*(sur: PSurface, x, y, w: Natural, Color: TColor) =
|
||||||
## draws a horizontal line from (x,y) to (x+w-1, h).
|
## draws a horizontal line from (x,y) to (x+w-1, y).
|
||||||
var video = cast[PPixels](sur.s.pixels)
|
var video = cast[PPixels](sur.s.pixels)
|
||||||
var pitch = sur.s.pitch div ColSize
|
var pitch = sur.s.pitch div ColSize
|
||||||
|
|
||||||
|
|
@ -264,44 +276,6 @@ proc drawVerLine*(sur: PSurface, x, y, h: Natural, Color: TColor) =
|
||||||
for i in 0 .. min(sur.s.h-y, h-1)-1:
|
for i in 0 .. min(sur.s.h-y, h-1)-1:
|
||||||
setPix(video, pitch, x, y + i, color)
|
setPix(video, pitch, x, y + i, color)
|
||||||
|
|
||||||
proc drawLine2*(sur: PSurface, p0, p1: TPoint, color: TColor) =
|
|
||||||
## Draws a line from ``p0`` to ``p1``, using the Bresenham's line algorithm
|
|
||||||
var (x0, x1, y0, y1) = (p0.x, p1.x, p0.y, p1.y)
|
|
||||||
|
|
||||||
if x0 >= sur.s.w: x0 = sur.s.w-1
|
|
||||||
if x1 >= sur.s.w: x1 = sur.s.w-1
|
|
||||||
if y0 >= sur.s.h: y0 = sur.s.h-1
|
|
||||||
if y1 >= sur.s.h: y1 = sur.s.h-1
|
|
||||||
|
|
||||||
var video = cast[PPixels](sur.s.pixels)
|
|
||||||
var pitch = sur.s.pitch div ColSize
|
|
||||||
|
|
||||||
var steep = abs(y1 - y0) > abs(x1 - x0)
|
|
||||||
if steep:
|
|
||||||
swap(x0, y0)
|
|
||||||
swap(x1, y1)
|
|
||||||
if x0 > x1:
|
|
||||||
swap(x0, x1)
|
|
||||||
swap(y0, y1)
|
|
||||||
|
|
||||||
var deltax = x1 - x0
|
|
||||||
var deltay = abs(y1 - y0)
|
|
||||||
var error = deltax div 2
|
|
||||||
|
|
||||||
var ystep: int
|
|
||||||
var y = y0
|
|
||||||
if y0 < y1: ystep = 1 else: ystep = -1
|
|
||||||
|
|
||||||
for x in x0..x1:
|
|
||||||
if steep:
|
|
||||||
setPix(video, pitch, y, x, color)
|
|
||||||
else:
|
|
||||||
setPix(video, pitch, x, y, color)
|
|
||||||
error = error - deltay
|
|
||||||
if error < 0:
|
|
||||||
y = y + ystep
|
|
||||||
error = error + deltax
|
|
||||||
|
|
||||||
proc fillCircle*(s: PSurface, p: TPoint, r: Natural, color: TColor) =
|
proc fillCircle*(s: PSurface, p: TPoint, r: Natural, color: TColor) =
|
||||||
## draws a circle with center `p` and radius `r` with the given color
|
## draws a circle with center `p` and radius `r` with the given color
|
||||||
## onto the surface `sur` and fills it.
|
## onto the surface `sur` and fills it.
|
||||||
|
|
@ -361,22 +335,18 @@ proc fillRect*(sur: PSurface, r: TRect, col: TColor) =
|
||||||
proc Plot4EllipsePoints(sur: PSurface, CX, CY, X, Y: Natural, col: TColor) =
|
proc Plot4EllipsePoints(sur: PSurface, CX, CY, X, Y: Natural, col: TColor) =
|
||||||
var video = cast[PPixels](sur.s.pixels)
|
var video = cast[PPixels](sur.s.pixels)
|
||||||
var pitch = sur.s.pitch div ColSize
|
var pitch = sur.s.pitch div ColSize
|
||||||
|
if CX+X <= sur.s.w-1:
|
||||||
|
if CY+Y <= sur.s.h-1: setPix(video, pitch, CX+X, CY+Y, col)
|
||||||
|
if CY-Y <= sur.s.h-1: setPix(video, pitch, CX+X, CY-Y, col)
|
||||||
|
if CX-X <= sur.s.w-1:
|
||||||
|
if CY+Y <= sur.s.h-1: setPix(video, pitch, CX-X, CY+Y, col)
|
||||||
|
if CY-Y <= sur.s.h-1: setPix(video, pitch, CX-X, CY-Y, col)
|
||||||
|
|
||||||
if CX+X <= sur.s.w-1 and CY+Y <= sur.s.h-1:
|
proc drawEllipse*(sur: PSurface, CX, CY, XRadius, YRadius: Natural,
|
||||||
setPix(video, pitch, CX+X, CY+Y, col)
|
col: TColor) =
|
||||||
|
## Draws an ellipse, ``CX`` and ``CY`` specify the center X and Y of the
|
||||||
if CX-X <= sur.s.w-1 and CY+Y <= sur.s.h-1:
|
## ellipse, ``XRadius`` and ``YRadius`` specify half the width and height
|
||||||
setPix(video, pitch, CX-X, CY+Y, col)
|
## of the ellipse.
|
||||||
|
|
||||||
if CX-X <= sur.s.w-1 and CY-Y <= sur.s.h-1:
|
|
||||||
setPix(video, pitch, CX-X, CY-Y, col)
|
|
||||||
|
|
||||||
if CX+X <= sur.s.w-1 and CY-Y <= sur.s.h-1:
|
|
||||||
setPix(video, pitch, CX+X, CY-Y, col)
|
|
||||||
|
|
||||||
proc drawEllipse*(sur: PSurface, CX, CY, XRadius, YRadius: Natural, col: TColor) =
|
|
||||||
## Draws an ellipse, ``CX`` and ``CY`` specify the center X and Y of the ellipse,
|
|
||||||
## ``XRadius`` and ``YRadius`` specify half the width and height of the ellipse.
|
|
||||||
var
|
var
|
||||||
X, Y: Natural
|
X, Y: Natural
|
||||||
XChange, YChange: Natural
|
XChange, YChange: Natural
|
||||||
|
|
@ -438,18 +408,15 @@ proc plotAA(sur: PSurface, x, y, c: float, color: TColor) =
|
||||||
setPix(video, pitch, x.toInt(), y.toInt(),
|
setPix(video, pitch, x.toInt(), y.toInt(),
|
||||||
pixColor.intensity(1.0 - c) + color.intensity(c))
|
pixColor.intensity(1.0 - c) + color.intensity(c))
|
||||||
|
|
||||||
import math
|
proc ipart(x: float): float = return x.trunc()
|
||||||
proc ipart(x: float): float =
|
proc fpart(x: float): float = return x - ipart(x)
|
||||||
return x.trunc()
|
proc rfpart(x: float): float = return 1.0 - fpart(x)
|
||||||
proc fpart(x: float): float =
|
|
||||||
return x - ipart(x)
|
proc drawLineAA(sur: PSurface, p1, p2: TPoint, color: TColor) =
|
||||||
proc rfpart(x: float): float =
|
## Draws a anti-aliased line from ``p1`` to ``p2``, using Xiaolin Wu's
|
||||||
return 1.0 - fpart(x)
|
## line algorithm
|
||||||
proc drawLineAA(sur: PSurface, p1: TPoint, p2: TPoint, color: TColor) =
|
|
||||||
## Draws a anti-aliased line from ``p1`` to ``p2``, using Xiaolin Wu's line algorithm
|
|
||||||
var (x1, x2, y1, y2) = (p1.x.toFloat(), p2.x.toFloat(),
|
var (x1, x2, y1, y2) = (p1.x.toFloat(), p2.x.toFloat(),
|
||||||
p1.y.toFloat(), p2.y.toFloat())
|
p1.y.toFloat(), p2.y.toFloat())
|
||||||
|
|
||||||
var dx = x2 - x1
|
var dx = x2 - x1
|
||||||
var dy = y2 - y1
|
var dy = y2 - y1
|
||||||
if abs(dx) < abs(dy):
|
if abs(dx) < abs(dy):
|
||||||
|
|
@ -483,26 +450,27 @@ proc drawLineAA(sur: PSurface, p1: TPoint, p2: TPoint, color: TColor) =
|
||||||
sur.plotAA(x.toFloat(), ipart(intery) + 1.0, fpart(intery), color)
|
sur.plotAA(x.toFloat(), ipart(intery) + 1.0, fpart(intery), color)
|
||||||
intery = intery + gradient
|
intery = intery + gradient
|
||||||
|
|
||||||
|
template withEvents(surf: PSurface, event: expr, actions: stmt): stmt =
|
||||||
|
while True:
|
||||||
|
var event: SDL.TEvent
|
||||||
|
if SDL.PollEvent(addr(event)) == 1:
|
||||||
|
actions
|
||||||
|
|
||||||
if sdl.Init(sdl.INIT_VIDEO) < 0:
|
if sdl.Init(sdl.INIT_VIDEO) < 0: raiseEGraphics()
|
||||||
echo "sdl init failed: " & $SDL.GetError()
|
if sdl_ttf.Init() < 0: raiseEGraphics()
|
||||||
|
|
||||||
if sdl_ttf.Init() < 0:
|
|
||||||
echo "sdl_ttf init failed: " & $SDL.GetError()
|
|
||||||
|
|
||||||
when isMainModule:
|
when isMainModule:
|
||||||
#var txtSurf = drawText(
|
|
||||||
|
|
||||||
var surf = newScreenSurface(800, 600)
|
var surf = newScreenSurface(800, 600)
|
||||||
var r: TRect = (0, 0, 900, 900)
|
var r: TRect = (0, 0, 900, 900)
|
||||||
|
|
||||||
# Draw the shapes
|
# Draw the shapes
|
||||||
surf.fillRect(r, colWhite)
|
surf.fillRect(r, colWhite)
|
||||||
surf.drawLineAA((100, 170), (400, 471), colTan)
|
surf.drawLineAA((100, 170), (400, 471), colTan)
|
||||||
surf.drawLine2((100, 170), (400, 471), colRed)
|
surf.drawLine((100, 170), (400, 471), colRed)
|
||||||
|
|
||||||
surf.drawEllipse(200, 300, 200, 30, colSeaGreen)
|
surf.drawEllipse(200, 300, 200, 30, colSeaGreen)
|
||||||
surf.drawHorLine(1, 300, 400, colViolet) # Check if the ellipse is the size it's suppose to be.
|
surf.drawHorLine(1, 300, 400, colViolet)
|
||||||
|
# Check if the ellipse is the size it's suppose to be.
|
||||||
surf.drawVerLine(200, 300 - 30 + 1, 60, colViolet) # ^^ | i suppose it is
|
surf.drawVerLine(200, 300 - 30 + 1, 60, colViolet) # ^^ | i suppose it is
|
||||||
|
|
||||||
surf.drawEllipse(400, 300, 300, 300, colOrange)
|
surf.drawEllipse(400, 300, 300, 300, colOrange)
|
||||||
|
|
@ -512,35 +480,36 @@ when isMainModule:
|
||||||
surf.drawVerLine(5, 60, 800, colRed)
|
surf.drawVerLine(5, 60, 800, colRed)
|
||||||
surf.drawCircle((600, 500), 60, colRed)
|
surf.drawCircle((600, 500), 60, colRed)
|
||||||
|
|
||||||
surf.drawText((300, 300), "VeraMono.ttf", "TEST", colMidnightBlue, 150)
|
#surf.drawText((300, 300), "TEST", colMidnightBlue)
|
||||||
var textSize = textBounds("VeraMono.ttf", 150, "TEST")
|
#var textSize = textBounds("TEST")
|
||||||
surf.drawText((300, 300 + textSize.height), "VeraMono.ttf", $textSize.width & ", " & $textSize.height, colDarkGreen, 50)
|
#surf.drawText((300, 300 + textSize.height), $textSize.width & ", " &
|
||||||
|
# $textSize.height, colDarkGreen)
|
||||||
|
|
||||||
var mouseStartX = 0
|
var mouseStartX = 0
|
||||||
var mouseStartY = 0
|
var mouseStartY = 0
|
||||||
withEvents(surf, event):
|
withEvents(surf, event):
|
||||||
case event.theType:
|
case event.kind:
|
||||||
of SDL.QUITEV:
|
of SDL.QUITEV:
|
||||||
break
|
break
|
||||||
of SDL.KEYDOWN:
|
of SDL.KEYDOWN:
|
||||||
if event.key.keysym.sym == SDL.K_LEFT:
|
if event.sym == SDL.K_LEFT:
|
||||||
echo(event.key.keysym.sym)
|
echo(event.sym)
|
||||||
surf.drawHorLine(395, 300, 5, colPaleGoldenRod)
|
surf.drawHorLine(395, 300, 5, colPaleGoldenRod)
|
||||||
echo("Drawing")
|
echo("Drawing")
|
||||||
else:
|
else:
|
||||||
echo(event.key.keysym.sym)
|
echo(event.sym)
|
||||||
of SDL.MOUSEBUTTONDOWN:
|
of SDL.MOUSEBUTTONDOWN:
|
||||||
# button.x/y is F* UP!
|
# button.x/y is F* UP!
|
||||||
echo("MOUSEDOWN", event.button.x)
|
echo("MOUSEDOWN ", event.x)
|
||||||
mouseStartX = event.button.x
|
mouseStartX = event.x
|
||||||
mouseStartY = event.button.y
|
mouseStartY = event.y
|
||||||
|
|
||||||
of SDL.MOUSEBUTTONUP:
|
of SDL.MOUSEBUTTONUP:
|
||||||
echo("MOUSEUP ", mouseStartX)
|
echo("MOUSEUP ", mouseStartX)
|
||||||
if mouseStartX != 0 and mouseStartY != 0:
|
if mouseStartX != 0 and mouseStartY != 0:
|
||||||
echo(mouseStartX, "->", int(event.button.x))
|
echo(mouseStartX, "->", int(event.x))
|
||||||
surf.drawLineAA((mouseStartX, MouseStartY),
|
surf.drawLineAA((mouseStartX, MouseStartY),
|
||||||
(int(event.button.x), int(event.button.y)), colPaleGoldenRod)
|
(int(event.x), int(event.y)), colPaleGoldenRod)
|
||||||
mouseStartX = 0
|
mouseStartX = 0
|
||||||
mouseStartY = 0
|
mouseStartY = 0
|
||||||
|
|
||||||
|
|
|
||||||
4189
lib/oldwrappers/zip/libzip_all.c
Executable file
4189
lib/oldwrappers/zip/libzip_all.c
Executable file
File diff suppressed because it is too large
Load diff
|
|
@ -20,7 +20,7 @@
|
||||||
##
|
##
|
||||||
## Every tag in the resulting tree is in lower case.
|
## Every tag in the resulting tree is in lower case.
|
||||||
##
|
##
|
||||||
## **Note:** The resulting ``PXmlNode``s already use the ``clientData`` field,
|
## **Note:** The resulting ``PXmlNode`` already use the ``clientData`` field,
|
||||||
## so it cannot be used by clients of this library.
|
## so it cannot be used by clients of this library.
|
||||||
|
|
||||||
import strutils, streams, parsexml, xmltree, unicode, strtabs
|
import strutils, streams, parsexml, xmltree, unicode, strtabs
|
||||||
|
|
|
||||||
|
|
@ -284,14 +284,14 @@ proc post*(url: string, extraHeaders = "", body = "",
|
||||||
## | POST's ``body`` to the ``url`` and returns a ``TResponse`` object.
|
## | POST's ``body`` to the ``url`` and returns a ``TResponse`` object.
|
||||||
## | This proc adds the necessary Content-Length header.
|
## | This proc adds the necessary Content-Length header.
|
||||||
## | This proc also handles redirection.
|
## | This proc also handles redirection.
|
||||||
extraHeaders.add("Content-Length: " & $len(body) & "\c\L")
|
var xh = extraHeaders & "Content-Length: " & $len(body) & "\c\L"
|
||||||
result = request(url, httpPOST, extraHeaders, body)
|
result = request(url, httpPOST, xh, body)
|
||||||
for i in 1..maxRedirects:
|
for i in 1..maxRedirects:
|
||||||
if result.status.redirection():
|
if result.status.redirection():
|
||||||
var locationHeader = result.headers["Location"]
|
var locationHeader = result.headers["Location"]
|
||||||
if locationHeader == "": httpError("location header expected")
|
if locationHeader == "": httpError("location header expected")
|
||||||
var meth = if result.status != "307": httpGet else: httpPost
|
var meth = if result.status != "307": httpGet else: httpPost
|
||||||
result = request(locationHeader, meth, extraHeaders, body)
|
result = request(locationHeader, meth, xh, body)
|
||||||
|
|
||||||
proc postContent*(url: string, extraHeaders = "", body = ""): string =
|
proc postContent*(url: string, extraHeaders = "", body = ""): string =
|
||||||
## | POST's ``body`` to ``url`` and returns the response's body as a string
|
## | POST's ``body`` to ``url`` and returns the response's body as a string
|
||||||
|
|
|
||||||
|
|
@ -108,7 +108,8 @@ type
|
||||||
|
|
||||||
# Nodes should be reference counted to make the `copy` operation very fast!
|
# Nodes should be reference counted to make the `copy` operation very fast!
|
||||||
# However, this is difficult to achieve: modify(n[0][1]) should propagate to
|
# However, this is difficult to achieve: modify(n[0][1]) should propagate to
|
||||||
# its father. How to do this without back references?
|
# its father. How to do this without back references? Hm, BS, it works without
|
||||||
|
# them.
|
||||||
|
|
||||||
proc `[]`* (n: PNimrodNode, i: int): PNimrodNode {.magic: "NChild".}
|
proc `[]`* (n: PNimrodNode, i: int): PNimrodNode {.magic: "NChild".}
|
||||||
## get `n`'s `i`'th child.
|
## get `n`'s `i`'th child.
|
||||||
|
|
|
||||||
|
|
@ -319,12 +319,12 @@ proc JoinPath*(head, tail: string): string {.noSideEffect.} =
|
||||||
##
|
##
|
||||||
## For example on Unix:
|
## For example on Unix:
|
||||||
##
|
##
|
||||||
## ..code-block:: nimrod
|
## .. code-block:: nimrod
|
||||||
## JoinPath("usr", "lib")
|
## JoinPath("usr", "lib")
|
||||||
##
|
##
|
||||||
## results in:
|
## results in:
|
||||||
##
|
##
|
||||||
## ..code-block:: nimrod
|
## .. code-block:: nimrod
|
||||||
## "usr/lib"
|
## "usr/lib"
|
||||||
##
|
##
|
||||||
## If head is the empty string, tail is returned.
|
## If head is the empty string, tail is returned.
|
||||||
|
|
@ -375,6 +375,7 @@ proc SplitPath*(path: string): tuple[head, tail: string] {.noSideEffect.} =
|
||||||
## ``JoinPath(head, tail) == path``.
|
## ``JoinPath(head, tail) == path``.
|
||||||
##
|
##
|
||||||
## Examples:
|
## Examples:
|
||||||
|
##
|
||||||
## .. code-block:: nimrod
|
## .. code-block:: nimrod
|
||||||
## SplitPath("usr/local/bin") -> ("usr/local", "bin")
|
## SplitPath("usr/local/bin") -> ("usr/local", "bin")
|
||||||
## SplitPath("usr/local/bin/") -> ("usr/local/bin", "")
|
## SplitPath("usr/local/bin/") -> ("usr/local/bin", "")
|
||||||
|
|
@ -399,8 +400,8 @@ proc parentDir*(path: string): string {.noSideEffect.} =
|
||||||
##
|
##
|
||||||
## This is often the same as the ``head`` result of ``splitPath``.
|
## This is often the same as the ``head`` result of ``splitPath``.
|
||||||
## If there is no parent, ``path`` is returned.
|
## If there is no parent, ``path`` is returned.
|
||||||
## Example: ``parentDir("/usr/local/bin") == "/usr/local"``.
|
## | Example: ``parentDir("/usr/local/bin") == "/usr/local"``.
|
||||||
## Example: ``parentDir("/usr/local/bin/") == "/usr/local"``.
|
## | Example: ``parentDir("/usr/local/bin/") == "/usr/local"``.
|
||||||
var
|
var
|
||||||
sepPos = -1
|
sepPos = -1
|
||||||
q = 1
|
q = 1
|
||||||
|
|
@ -834,7 +835,7 @@ iterator walkDir*(dir: string): tuple[kind: TPathComponent, path: string] =
|
||||||
## for kind, path in walkDir("dirA"):
|
## for kind, path in walkDir("dirA"):
|
||||||
## echo(path)
|
## echo(path)
|
||||||
##
|
##
|
||||||
## produces this output (though not necessarily in this order!)::
|
## produces this output (but not necessarily in this order!)::
|
||||||
## dirA/dirB
|
## dirA/dirB
|
||||||
## dirA/dirC
|
## dirA/dirC
|
||||||
## dirA/fileA1.txt
|
## dirA/fileA1.txt
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
# Nimrod's Runtime Library
|
# Nimrod's Runtime Library
|
||||||
# (c) Copyright 2008 Andreas Rumpf
|
# (c) Copyright 2010 Andreas Rumpf
|
||||||
#
|
#
|
||||||
# See the file "copying.txt", included in this
|
# See the file "copying.txt", included in this
|
||||||
# distribution, for details about the copyright.
|
# distribution, for details about the copyright.
|
||||||
|
|
@ -17,11 +17,11 @@
|
||||||
##
|
##
|
||||||
## .. include:: doc/mytest.cfg
|
## .. include:: doc/mytest.cfg
|
||||||
## :literal:
|
## :literal:
|
||||||
## The file ``tests/tparscfg.nim`` demonstrates how to use the
|
## The file ``examples/parsecfgex.nim`` demonstrates how to use the
|
||||||
## configuration file parser:
|
## configuration file parser:
|
||||||
##
|
##
|
||||||
## .. code-block:: nimrod
|
## .. code-block:: nimrod
|
||||||
## :file: tests/tparscfg.nim
|
## :file: examples/parsecfgex.nim
|
||||||
|
|
||||||
|
|
||||||
import
|
import
|
||||||
|
|
|
||||||
|
|
@ -1190,7 +1190,7 @@ proc eat(p: var TPegParser, kind: TTokKind) =
|
||||||
|
|
||||||
proc parseExpr(p: var TPegParser): TPeg
|
proc parseExpr(p: var TPegParser): TPeg
|
||||||
|
|
||||||
proc getNonTerminal(p: TPegParser, name: string): PNonTerminal =
|
proc getNonTerminal(p: var TPegParser, name: string): PNonTerminal =
|
||||||
for i in 0..high(p.nonterms):
|
for i in 0..high(p.nonterms):
|
||||||
result = p.nonterms[i]
|
result = p.nonterms[i]
|
||||||
if cmpIgnoreStyle(result.name, name) == 0: return
|
if cmpIgnoreStyle(result.name, name) == 0: return
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
# Nimrod's Runtime Library
|
# Nimrod's Runtime Library
|
||||||
# (c) Copyright 2008 Andreas Rumpf
|
# (c) Copyright 2010 Andreas Rumpf
|
||||||
#
|
#
|
||||||
# See the file "copying.txt", included in this
|
# See the file "copying.txt", included in this
|
||||||
# distribution, for details about the copyright.
|
# distribution, for details about the copyright.
|
||||||
|
|
@ -36,7 +36,7 @@ proc newStringTable*(keyValuePairs: openarray[string],
|
||||||
## var mytab = newStringTable("key1", "val1", "key2", "val2",
|
## var mytab = newStringTable("key1", "val1", "key2", "val2",
|
||||||
## modeCaseInsensitive)
|
## modeCaseInsensitive)
|
||||||
|
|
||||||
proc newStringTable*(mode: TStringTableMode = modeCaseSensitive): PStringTable
|
proc newStringTable*(mode: TStringTableMode): PStringTable
|
||||||
## creates a new string table that is empty.
|
## creates a new string table that is empty.
|
||||||
|
|
||||||
proc `[]=`*(t: PStringTable, key, val: string)
|
proc `[]=`*(t: PStringTable, key, val: string)
|
||||||
|
|
@ -79,7 +79,7 @@ const
|
||||||
growthFactor = 2
|
growthFactor = 2
|
||||||
startSize = 64
|
startSize = 64
|
||||||
|
|
||||||
proc newStringTable(mode: TStringTableMode = modeCaseSensitive): PStringTable =
|
proc newStringTable(mode: TStringTableMode): PStringTable =
|
||||||
new(result)
|
new(result)
|
||||||
result.mode = mode
|
result.mode = mode
|
||||||
result.counter = 0
|
result.counter = 0
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@
|
||||||
## This module is based on Python's Unidecode module by Tomaz Solc,
|
## This module is based on Python's Unidecode module by Tomaz Solc,
|
||||||
## which in turn is based on the ``Text::Unidecode`` Perl module by
|
## which in turn is based on the ``Text::Unidecode`` Perl module by
|
||||||
## Sean M. Burke
|
## Sean M. Burke
|
||||||
## (http://search.cpan.org/~sburke/Text-Unidecode-0.04/lib/Text/Unidecode.pm).
|
## (http://search.cpan.org/~sburke/Text-Unidecode-0.04/lib/Text/Unidecode.pm ).
|
||||||
##
|
##
|
||||||
## It provides a single proc that does Unicode to ASCII transliterations:
|
## It provides a single proc that does Unicode to ASCII transliterations:
|
||||||
## It finds the sequence of ASCII characters that is the closest approximation
|
## It finds the sequence of ASCII characters that is the closest approximation
|
||||||
|
|
@ -47,7 +47,7 @@ proc unidecode*(s: string): string =
|
||||||
## Example:
|
## Example:
|
||||||
##
|
##
|
||||||
## ..code-block:: nimrod
|
## ..code-block:: nimrod
|
||||||
## unidecode("\x53\x17\x4E\xB0")
|
## unidecode("\\x53\\x17\\x4E\\xB0")
|
||||||
##
|
##
|
||||||
## Results in: "Bei Jing"
|
## Results in: "Bei Jing"
|
||||||
##
|
##
|
||||||
|
|
|
||||||
|
|
@ -12,9 +12,9 @@
|
||||||
import macros, strtabs
|
import macros, strtabs
|
||||||
|
|
||||||
type
|
type
|
||||||
PXmlNode* = ref TXmlNode ## an XML tree consists of ``PXmlNode``s.
|
PXmlNode* = ref TXmlNode ## an XML tree consists of ``PXmlNode``'s.
|
||||||
|
|
||||||
TXmlNodeKind* = enum ## different kinds of ``PXmlNode``s
|
TXmlNodeKind* = enum ## different kinds of ``PXmlNode``'s
|
||||||
xnText, ## a text element
|
xnText, ## a text element
|
||||||
xnElement, ## an element with 0 or more children
|
xnElement, ## an element with 0 or more children
|
||||||
xnCData, ## a CDATA node
|
xnCData, ## a CDATA node
|
||||||
|
|
@ -39,7 +39,7 @@ proc newXmlNode(kind: TXmlNodeKind): PXmlNode =
|
||||||
result.k = kind
|
result.k = kind
|
||||||
|
|
||||||
proc newElement*(tag: string): PXmlNode =
|
proc newElement*(tag: string): PXmlNode =
|
||||||
## creates a new ``PXmlNode``. of kind ``xnText`` with the given `tag`.
|
## creates a new ``PXmlNode`` of kind ``xnText`` with the given `tag`.
|
||||||
result = newXmlNode(xnElement)
|
result = newXmlNode(xnElement)
|
||||||
result.fTag = tag
|
result.fTag = tag
|
||||||
result.s = @[]
|
result.s = @[]
|
||||||
|
|
@ -208,9 +208,14 @@ proc add*(result: var string, n: PXmlNode, indent = 0, indWidth = 2) =
|
||||||
result.add(n.fText)
|
result.add(n.fText)
|
||||||
result.add(';')
|
result.add(';')
|
||||||
|
|
||||||
|
const
|
||||||
|
xmlHeader* = "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n"
|
||||||
|
## header to use for complete XML output
|
||||||
|
|
||||||
proc `$`*(n: PXmlNode): string =
|
proc `$`*(n: PXmlNode): string =
|
||||||
## converts `n` into its string representation.
|
## converts `n` into its string representation. No ``<$xml ...$>`` declaration
|
||||||
result = "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>\n"
|
## is produced, so that the produced XML fragments are composable.
|
||||||
|
result = ""
|
||||||
result.add(n)
|
result.add(n)
|
||||||
|
|
||||||
proc newXmlTree*(tag: string, children: openArray[PXmlNode],
|
proc newXmlTree*(tag: string, children: openArray[PXmlNode],
|
||||||
|
|
@ -227,16 +232,21 @@ proc xmlConstructor(e: PNimrodNode): PNimrodNode {.compileTime.} =
|
||||||
var a = e[1]
|
var a = e[1]
|
||||||
if a.kind == nnkCall:
|
if a.kind == nnkCall:
|
||||||
result = newCall("newXmlTree", toStrLit(a[0]))
|
result = newCall("newXmlTree", toStrLit(a[0]))
|
||||||
var attrs = newCall("newStringTable", [])
|
var attrs = newNimNode(nnkBracket, a)
|
||||||
var bracket = newNimNode(nnkBracket, a)
|
var newStringTabCall = newCall("newStringTable", attrs,
|
||||||
|
newIdentNode("modeCaseSensitive"))
|
||||||
|
var elements = newNimNode(nnkBracket, a)
|
||||||
for i in 1..a.len-1:
|
for i in 1..a.len-1:
|
||||||
if a[i].kind == nnkExprEqExpr:
|
if a[i].kind == nnkExprEqExpr:
|
||||||
attrs.add(toStrLit(a[i][0]))
|
attrs.add(toStrLit(a[i][0]))
|
||||||
attrs.add(a[i][1])
|
attrs.add(a[i][1])
|
||||||
|
echo repr(attrs)
|
||||||
else:
|
else:
|
||||||
bracket.add(a[i])
|
elements.add(a[i])
|
||||||
result.add(bracket)
|
result.add(elements)
|
||||||
if attrs.len > 1: result.add(attrs)
|
if attrs.len > 1:
|
||||||
|
echo repr(newStringTabCall)
|
||||||
|
result.add(newStringTabCall)
|
||||||
else:
|
else:
|
||||||
result = newCall("newXmlTree", toStrLit(a))
|
result = newCall("newXmlTree", toStrLit(a))
|
||||||
|
|
||||||
|
|
@ -252,5 +262,3 @@ macro `<>`*(x: expr): expr =
|
||||||
##
|
##
|
||||||
result = xmlConstructor(x)
|
result = xmlConstructor(x)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -85,9 +85,6 @@ proc gnome_init*() =
|
||||||
proc bonobo_init*() =
|
proc bonobo_init*() =
|
||||||
init()
|
init()
|
||||||
|
|
||||||
proc xml_new*(fname: cstring, root: cstring, domain: cstring): PXML =
|
|
||||||
result = xml_new(fname, root, domain)
|
|
||||||
|
|
||||||
proc xml_new_from_memory*(buffer: cstring, size: int32, root: cstring,
|
proc xml_new_from_memory*(buffer: cstring, size: int32, root: cstring,
|
||||||
domain: cstring): PXML =
|
domain: cstring): PXML =
|
||||||
result = xml_new_from_buffer(buffer, size, root, domain)
|
result = xml_new_from_buffer(buffer, size, root, domain)
|
||||||
|
|
|
||||||
|
|
@ -799,9 +799,6 @@ type
|
||||||
here*: ptr byte
|
here*: ptr byte
|
||||||
stop*: ptr byte
|
stop*: ptr byte
|
||||||
|
|
||||||
TUnknown*{.final.} = object # first declare the pointer type
|
|
||||||
data1*: Pointer
|
|
||||||
|
|
||||||
PRWops* = ptr TRWops # now the pointer to function types
|
PRWops* = ptr TRWops # now the pointer to function types
|
||||||
TSeek* = proc (context: PRWops, offset: int, whence: int): int{.cdecl.}
|
TSeek* = proc (context: PRWops, offset: int, whence: int): int{.cdecl.}
|
||||||
TRead* = proc (context: PRWops, thePtr: Pointer, size: int, maxnum: int): int{.
|
TRead* = proc (context: PRWops, thePtr: Pointer, size: int, maxnum: int): int{.
|
||||||
|
|
@ -809,24 +806,15 @@ type
|
||||||
TWrite* = proc (context: PRWops, thePtr: Pointer, size: int, num: int): int{.
|
TWrite* = proc (context: PRWops, thePtr: Pointer, size: int, num: int): int{.
|
||||||
cdecl.}
|
cdecl.}
|
||||||
TClose* = proc (context: PRWops): int{.cdecl.} # the variant record itself
|
TClose* = proc (context: PRWops): int{.cdecl.} # the variant record itself
|
||||||
trange010 = range[0..2]
|
|
||||||
TRWops*{.final.} = object
|
TRWops*{.final.} = object
|
||||||
seek*: TSeek
|
seek*: TSeek
|
||||||
read*: TRead
|
read*: TRead
|
||||||
write*: TWrite
|
write*: TWrite
|
||||||
closeFile*: TClose # a keyword as name is not allowed
|
closeFile*: TClose # a keyword as name is not allowed
|
||||||
# be warned! structure alignment may arise at this point
|
# be warned! structure alignment may arise at this point
|
||||||
case theType*: trange010
|
theType*: cint
|
||||||
of trange010(0):
|
|
||||||
stdio*: TStdio
|
|
||||||
|
|
||||||
of trange010(1):
|
|
||||||
mem*: TMem
|
mem*: TMem
|
||||||
|
|
||||||
of trange010(2):
|
|
||||||
unknown*: TUnknown
|
|
||||||
|
|
||||||
|
|
||||||
RWops* = TRWops # SDL_timer.h types
|
RWops* = TRWops # SDL_timer.h types
|
||||||
# Function prototype for the timer callback function
|
# Function prototype for the timer callback function
|
||||||
TTimerCallback* = proc (interval: int32): int32{.cdecl.}
|
TTimerCallback* = proc (interval: int32): int32{.cdecl.}
|
||||||
|
|
@ -1014,7 +1002,8 @@ type
|
||||||
|
|
||||||
TJoyButtonEvent*{.final.} = object # SDL_JOYBUTTONDOWN or SDL_JOYBUTTONUP
|
TJoyButtonEvent*{.final.} = object # SDL_JOYBUTTONDOWN or SDL_JOYBUTTONUP
|
||||||
# The "window resized" event
|
# The "window resized" event
|
||||||
# When you get this event, you are responsible for setting a new video
|
# When you get this event, you are
|
||||||
|
# responsible for setting a new video
|
||||||
# mode with the new width and height.
|
# mode with the new width and height.
|
||||||
which*: byte # The joystick device index
|
which*: byte # The joystick device index
|
||||||
button*: byte # The joystick button index
|
button*: byte # The joystick button index
|
||||||
|
|
@ -1022,12 +1011,12 @@ type
|
||||||
|
|
||||||
TResizeEvent*{.final.} = object # SDL_VIDEORESIZE
|
TResizeEvent*{.final.} = object # SDL_VIDEORESIZE
|
||||||
# A user-defined event type
|
# A user-defined event type
|
||||||
w*: int # New width
|
w*: cint # New width
|
||||||
h*: int # New height
|
h*: cint # New height
|
||||||
|
|
||||||
PUserEvent* = ptr TUserEvent
|
PUserEvent* = ptr TUserEvent
|
||||||
TUserEvent*{.final.} = object # SDL_USEREVENT through SDL_NUMEVENTS-1
|
TUserEvent*{.final.} = object # SDL_USEREVENT through SDL_NUMEVENTS-1
|
||||||
code*: int # User defined event code
|
code*: cint # User defined event code
|
||||||
data1*: Pointer # User defined data pointer
|
data1*: Pointer # User defined data pointer
|
||||||
data2*: Pointer # User defined data pointer
|
data2*: Pointer # User defined data pointer
|
||||||
|
|
||||||
|
|
@ -1108,46 +1097,59 @@ type
|
||||||
msg*: PSysWMmsg
|
msg*: PSysWMmsg
|
||||||
|
|
||||||
PEvent* = ptr TEvent
|
PEvent* = ptr TEvent
|
||||||
TEvent*{.final.} = object # This function sets up a filter to process all events before they
|
TEvent*{.final.} = object
|
||||||
|
# This function sets up a filter to process all events before they
|
||||||
# change internal state and are posted to the internal event queue.
|
# change internal state and are posted to the internal event queue.
|
||||||
#
|
|
||||||
# The filter is protypted as:
|
# The filter is protypted as:
|
||||||
case theType*: TEventKind # SDL_NOEVENT, SDL_QUITEV: ();
|
case kind*: TEventKind # SDL_NOEVENT, SDL_QUITEV: ();
|
||||||
of ACTIVEEVENT:
|
of ACTIVEEVENT:
|
||||||
active*: TActiveEvent
|
gain*: byte # Whether given states were gained or lost (1/0)
|
||||||
|
state*: byte # A mask of the focus states
|
||||||
of KEYDOWN, KEYUP:
|
of KEYDOWN, KEYUP:
|
||||||
key*: TKeyboardEvent
|
keystate*: byte # SDL_PRESSED or SDL_RELEASED
|
||||||
|
scancode*: byte # hardware specific scancode
|
||||||
|
sym*: TKey # SDL virtual keysym
|
||||||
|
modifier*: TMod # current key modifiers
|
||||||
|
unicode*: UInt16 # translated character
|
||||||
of MOUSEMOTION:
|
of MOUSEMOTION:
|
||||||
motion*: TMouseMotionEvent
|
motionState*: byte # The current button state
|
||||||
|
motionX*, motionY*: UInt16 # The X/Y coordinates of the mouse
|
||||||
|
xrel*: int16 # The relative motion in the X direction
|
||||||
|
yrel*: int16 # The relative motion in the Y direction
|
||||||
of MOUSEBUTTONDOWN, MOUSEBUTTONUP:
|
of MOUSEBUTTONDOWN, MOUSEBUTTONUP:
|
||||||
button*: TMouseButtonEvent
|
button*: byte # The mouse button index
|
||||||
|
buttonState*: byte # SDL_PRESSED or SDL_RELEASED
|
||||||
|
align: byte
|
||||||
|
x*: UInt16 # The X coordinates of the mouse at press time
|
||||||
|
y*: UInt16 # The Y coordinates of the mouse at press time
|
||||||
of JOYAXISMOTION:
|
of JOYAXISMOTION:
|
||||||
jaxis*: TJoyAxisEvent
|
axis*: byte # The joystick axis index
|
||||||
|
value*: int16 # The axis value (range: -32768 to 32767)
|
||||||
of JOYBALLMOTION:
|
of JOYBALLMOTION:
|
||||||
jball*: TJoyBallEvent
|
ball*: byte # The joystick trackball index
|
||||||
|
joyXrel*: int16 # The relative motion in the X direction
|
||||||
|
joyYrel*: int16 # The relative motion in the Y direction
|
||||||
|
|
||||||
of JOYHATMOTION:
|
of JOYHATMOTION:
|
||||||
jhat*: TJoyHatEvent
|
hat*: byte # The joystick hat index
|
||||||
|
hatValue*: byte # The hat position value:
|
||||||
|
# 8 1 2
|
||||||
|
# 7 0 3
|
||||||
|
# 6 5 4
|
||||||
|
# Note that zero means the POV is centered.
|
||||||
|
|
||||||
of JOYBUTTONDOWN, JOYBUTTONUP:
|
of JOYBUTTONDOWN, JOYBUTTONUP:
|
||||||
jbutton*: TJoyButtonEvent
|
joybutton*: byte # The joystick button index
|
||||||
|
joyState*: byte # SDL_PRESSED or SDL_RELEASED
|
||||||
|
|
||||||
of VIDEORESIZE:
|
of VIDEORESIZE:
|
||||||
resize*: TResizeEvent
|
w*: cint # New width
|
||||||
|
h*: cint # New height
|
||||||
of USEREVENT:
|
of USEREVENT:
|
||||||
user*: TUserEvent
|
code*: cint # User defined event code
|
||||||
|
data1*: Pointer # User defined data pointer
|
||||||
of SYSWMEVENT:
|
data2*: Pointer # User defined data pointer
|
||||||
syswm*: TSysWMEvent
|
else: nil
|
||||||
|
|
||||||
else:
|
|
||||||
nil
|
|
||||||
|
|
||||||
|
|
||||||
TEventFilter* = proc (event: PEvent): int{.cdecl.} # SDL_video.h types
|
TEventFilter* = proc (event: PEvent): int{.cdecl.} # SDL_video.h types
|
||||||
|
|
@ -1209,8 +1211,8 @@ type
|
||||||
dst*: PPixelFormat
|
dst*: PPixelFormat
|
||||||
|
|
||||||
PSurface* = ptr TSurface
|
PSurface* = ptr TSurface
|
||||||
TBlit* = proc (src: PSurface, srcrect: PRect, dst: PSurface, dstrect: PRect): int{.
|
TBlit* = proc (src: PSurface, srcrect: PRect,
|
||||||
cdecl.}
|
dst: PSurface, dstrect: PRect): int{.cdecl.}
|
||||||
TSurface*{.final.} = object # Useful for determining the video hardware capabilities
|
TSurface*{.final.} = object # Useful for determining the video hardware capabilities
|
||||||
flags*: int32 # Read-only
|
flags*: int32 # Read-only
|
||||||
format*: PPixelFormat # Read-only
|
format*: PPixelFormat # Read-only
|
||||||
|
|
@ -1302,12 +1304,12 @@ type # This is the system-independent thread info struc
|
||||||
PWordArray* = ptr TWordArray
|
PWordArray* = ptr TWordArray
|
||||||
TWordArray* = array[0..16383, int16] # Generic procedure pointer
|
TWordArray* = array[0..16383, int16] # Generic procedure pointer
|
||||||
TProcedure* = proc () #------------------------------------------------------------------------------
|
TProcedure* = proc () #------------------------------------------------------------------------------
|
||||||
# initialization
|
# initialization
|
||||||
#------------------------------------------------------------------------------
|
#------------------------------------------------------------------------------
|
||||||
# This function loads the SDL dynamically linked library and initializes
|
# This function loads the SDL dynamically linked library and initializes
|
||||||
# the subsystems specified by 'flags' (and those satisfying dependencies)
|
# the subsystems specified by 'flags' (and those satisfying dependencies)
|
||||||
# Unless the SDL_INIT_NOPARACHUTE flag is set, it will install cleanup
|
# Unless the SDL_INIT_NOPARACHUTE flag is set, it will install cleanup
|
||||||
# signal handlers for some commonly ignored fatal signals (like SIGSEGV)
|
# signal handlers for some commonly ignored fatal signals (like SIGSEGV)
|
||||||
|
|
||||||
proc Init*(flags: int32): int{.cdecl, importc: "SDL_Init", dynlib: LibName.}
|
proc Init*(flags: int32): int{.cdecl, importc: "SDL_Init", dynlib: LibName.}
|
||||||
# This function initializes specific SDL subsystems
|
# This function initializes specific SDL subsystems
|
||||||
|
|
|
||||||
|
|
@ -178,10 +178,12 @@ const
|
||||||
|
|
||||||
type
|
type
|
||||||
PFont* = ptr Tfont
|
PFont* = ptr Tfont
|
||||||
TFont*{.final.} = object # This macro can be used to fill a version structure with the compile-time
|
TFont{.final.} = object
|
||||||
# version of the SDL_ttf library.
|
|
||||||
|
|
||||||
|
|
||||||
|
# This macro can be used to fill a version structure with the compile-time
|
||||||
|
# version of the SDL_ttf library.
|
||||||
|
|
||||||
proc Linked_Version*(): sdl.Pversion{.cdecl, importc: "TTF_Linked_Version",
|
proc Linked_Version*(): sdl.Pversion{.cdecl, importc: "TTF_Linked_Version",
|
||||||
dynlib: ttfLibName.}
|
dynlib: ttfLibName.}
|
||||||
# This function tells the library whether UNICODE text is generally
|
# This function tells the library whether UNICODE text is generally
|
||||||
|
|
|
||||||
4189
lib/wrappers/zip/libzip_all.c
Executable file
4189
lib/wrappers/zip/libzip_all.c
Executable file
File diff suppressed because it is too large
Load diff
|
|
@ -1093,15 +1093,16 @@ proc genRepr(p: BProc, e: PNode, d: var TLoc) =
|
||||||
ropef("reprSet($1, $2)", [rdLoc(a), genTypeInfo(p.module, t)]))
|
ropef("reprSet($1, $2)", [rdLoc(a), genTypeInfo(p.module, t)]))
|
||||||
of tyOpenArray:
|
of tyOpenArray:
|
||||||
useMagic(p.module, "reprOpenArray")
|
useMagic(p.module, "reprOpenArray")
|
||||||
|
var b: TLoc
|
||||||
case a.t.kind
|
case a.t.kind
|
||||||
of tyOpenArray: putIntoDest(p, d, e.typ, ropef("$1, $1Len0", [rdLoc(a)]))
|
of tyOpenArray: putIntoDest(p, b, e.typ, rdLoc(a))
|
||||||
of tyString, tySequence:
|
of tyString, tySequence:
|
||||||
putIntoDest(p, d, e.typ, ropef("$1->data, $1->Sup.len", [rdLoc(a)]))
|
putIntoDest(p, b, e.typ, ropef("$1->data, $1->Sup.len", [rdLoc(a)]))
|
||||||
of tyArray, tyArrayConstr:
|
of tyArray, tyArrayConstr:
|
||||||
putIntoDest(p, d, e.typ,
|
putIntoDest(p, b, e.typ,
|
||||||
ropef("$1, $2", [rdLoc(a), toRope(lengthOrd(a.t))]))
|
ropef("$1, $2", [rdLoc(a), toRope(lengthOrd(a.t))]))
|
||||||
else: InternalError(e.sons[0].info, "genRepr()")
|
else: InternalError(e.sons[0].info, "genRepr()")
|
||||||
putIntoDest(p, d, e.typ, ropef("reprOpenArray($1, $2)", [rdLoc(d),
|
putIntoDest(p, d, e.typ, ropef("reprOpenArray($1, $2)", [rdLoc(b),
|
||||||
genTypeInfo(p.module, elemType(t))]))
|
genTypeInfo(p.module, elemType(t))]))
|
||||||
of tyCString, tyArray, tyArrayConstr, tyRef, tyPtr, tyPointer, tyNil,
|
of tyCString, tyArray, tyArrayConstr, tyRef, tyPtr, tyPointer, tyNil,
|
||||||
tySequence:
|
tySequence:
|
||||||
|
|
|
||||||
|
|
@ -259,6 +259,10 @@ proc evalCall(c: PEvalContext, n: PNode): PNode =
|
||||||
if n.typ != nil: result = d.params[0]
|
if n.typ != nil: result = d.params[0]
|
||||||
popStackFrame(c)
|
popStackFrame(c)
|
||||||
|
|
||||||
|
proc aliasNeeded(n: PNode, flags: TEvalFlags): bool =
|
||||||
|
result = efLValue in flags or n.typ == nil or
|
||||||
|
n.typ.kind in {tyExpr, tyStmt, tyTypeDesc}
|
||||||
|
|
||||||
proc evalVariable(c: PStackFrame, sym: PSym, flags: TEvalFlags): PNode =
|
proc evalVariable(c: PStackFrame, sym: PSym, flags: TEvalFlags): PNode =
|
||||||
# We need to return a node to the actual value,
|
# We need to return a node to the actual value,
|
||||||
# which can be modified.
|
# which can be modified.
|
||||||
|
|
@ -269,7 +273,7 @@ proc evalVariable(c: PStackFrame, sym: PSym, flags: TEvalFlags): PNode =
|
||||||
if result == nil: result = emptyNode
|
if result == nil: result = emptyNode
|
||||||
return
|
return
|
||||||
result = IdNodeTableGet(x.mapping, sym)
|
result = IdNodeTableGet(x.mapping, sym)
|
||||||
if efLValue notin flags: result = copyTree(result)
|
if not aliasNeeded(result, flags): result = copyTree(result)
|
||||||
if result != nil: return
|
if result != nil: return
|
||||||
x = x.next
|
x = x.next
|
||||||
result = emptyNode
|
result = emptyNode
|
||||||
|
|
@ -286,7 +290,7 @@ proc evalArrayAccess(c: PEvalContext, n: PNode, flags: TEvalFlags): PNode =
|
||||||
of nkBracket, nkPar, nkMetaNode:
|
of nkBracket, nkPar, nkMetaNode:
|
||||||
if (idx >= 0) and (idx < sonsLen(x)): result = x.sons[int(idx)]
|
if (idx >= 0) and (idx < sonsLen(x)): result = x.sons[int(idx)]
|
||||||
else: stackTrace(c, n, errIndexOutOfBounds)
|
else: stackTrace(c, n, errIndexOutOfBounds)
|
||||||
if efLValue notin flags: result = copyTree(result)
|
if not aliasNeeded(result, flags): result = copyTree(result)
|
||||||
of nkStrLit..nkTripleStrLit:
|
of nkStrLit..nkTripleStrLit:
|
||||||
if efLValue in flags:
|
if efLValue in flags:
|
||||||
InternalError(n.info, "cannot evaluate write access to char")
|
InternalError(n.info, "cannot evaluate write access to char")
|
||||||
|
|
@ -313,7 +317,7 @@ proc evalFieldAccess(c: PEvalContext, n: PNode, flags: TEvalFlags): PNode =
|
||||||
InternalError(n.info, "evalFieldAccess")
|
InternalError(n.info, "evalFieldAccess")
|
||||||
if x.sons[i].sons[0].sym.name.id == field.id:
|
if x.sons[i].sons[0].sym.name.id == field.id:
|
||||||
result = x.sons[i].sons[1]
|
result = x.sons[i].sons[1]
|
||||||
if efLValue in flags: result = copyTree(result)
|
if not aliasNeeded(result, flags): result = copyTree(result)
|
||||||
return
|
return
|
||||||
stackTrace(c, n, errFieldXNotFound, field.name.s)
|
stackTrace(c, n, errFieldXNotFound, field.name.s)
|
||||||
result = emptyNode
|
result = emptyNode
|
||||||
|
|
@ -705,7 +709,7 @@ proc evalMagicOrCall(c: PEvalContext, n: PNode): PNode =
|
||||||
of mAppendStrStr: result = evalAppendStrStr(c, n)
|
of mAppendStrStr: result = evalAppendStrStr(c, n)
|
||||||
of mAppendSeqElem: result = evalAppendSeqElem(c, n)
|
of mAppendSeqElem: result = evalAppendSeqElem(c, n)
|
||||||
of mNLen:
|
of mNLen:
|
||||||
result = evalAux(c, n.sons[1], {})
|
result = evalAux(c, n.sons[1], {efLValue})
|
||||||
if isSpecial(result): return
|
if isSpecial(result): return
|
||||||
var a = result
|
var a = result
|
||||||
result = newNodeIT(nkIntLit, n.info, n.typ)
|
result = newNodeIT(nkIntLit, n.info, n.typ)
|
||||||
|
|
@ -714,10 +718,10 @@ proc evalMagicOrCall(c: PEvalContext, n: PNode): PNode =
|
||||||
nil
|
nil
|
||||||
else: result.intVal = sonsLen(a)
|
else: result.intVal = sonsLen(a)
|
||||||
of mNChild:
|
of mNChild:
|
||||||
result = evalAux(c, n.sons[1], {})
|
result = evalAux(c, n.sons[1], {efLValue})
|
||||||
if isSpecial(result): return
|
if isSpecial(result): return
|
||||||
var a = result
|
var a = result
|
||||||
result = evalAux(c, n.sons[2], {})
|
result = evalAux(c, n.sons[2], {efLValue})
|
||||||
if isSpecial(result): return
|
if isSpecial(result): return
|
||||||
var k = getOrdValue(result)
|
var k = getOrdValue(result)
|
||||||
if not (a.kind in {nkEmpty..nkNilLit}) and (k >= 0) and (k < sonsLen(a)):
|
if not (a.kind in {nkEmpty..nkNilLit}) and (k >= 0) and (k < sonsLen(a)):
|
||||||
|
|
@ -730,10 +734,10 @@ proc evalMagicOrCall(c: PEvalContext, n: PNode): PNode =
|
||||||
result = evalAux(c, n.sons[1], {efLValue})
|
result = evalAux(c, n.sons[1], {efLValue})
|
||||||
if isSpecial(result): return
|
if isSpecial(result): return
|
||||||
var a = result
|
var a = result
|
||||||
result = evalAux(c, n.sons[2], {})
|
result = evalAux(c, n.sons[2], {efLValue})
|
||||||
if isSpecial(result): return
|
if isSpecial(result): return
|
||||||
var b = result
|
var b = result
|
||||||
result = evalAux(c, n.sons[3], {})
|
result = evalAux(c, n.sons[3], {efLValue})
|
||||||
if isSpecial(result): return
|
if isSpecial(result): return
|
||||||
var k = getOrdValue(b)
|
var k = getOrdValue(b)
|
||||||
if (k >= 0) and (k < sonsLen(a)) and not (a.kind in {nkEmpty..nkNilLit}):
|
if (k >= 0) and (k < sonsLen(a)) and not (a.kind in {nkEmpty..nkNilLit}):
|
||||||
|
|
@ -746,7 +750,7 @@ proc evalMagicOrCall(c: PEvalContext, n: PNode): PNode =
|
||||||
result = evalAux(c, n.sons[1], {efLValue})
|
result = evalAux(c, n.sons[1], {efLValue})
|
||||||
if isSpecial(result): return
|
if isSpecial(result): return
|
||||||
var a = result
|
var a = result
|
||||||
result = evalAux(c, n.sons[2], {})
|
result = evalAux(c, n.sons[2], {efLValue})
|
||||||
if isSpecial(result): return
|
if isSpecial(result): return
|
||||||
addSon(a, result)
|
addSon(a, result)
|
||||||
result = emptyNode
|
result = emptyNode
|
||||||
|
|
@ -754,7 +758,7 @@ proc evalMagicOrCall(c: PEvalContext, n: PNode): PNode =
|
||||||
result = evalAux(c, n.sons[1], {efLValue})
|
result = evalAux(c, n.sons[1], {efLValue})
|
||||||
if isSpecial(result): return
|
if isSpecial(result): return
|
||||||
var a = result
|
var a = result
|
||||||
result = evalAux(c, n.sons[2], {})
|
result = evalAux(c, n.sons[2], {efLValue})
|
||||||
if isSpecial(result): return
|
if isSpecial(result): return
|
||||||
for i in countup(0, sonsLen(result) - 1): addSon(a, result.sons[i])
|
for i in countup(0, sonsLen(result) - 1): addSon(a, result.sons[i])
|
||||||
result = emptyNode
|
result = emptyNode
|
||||||
|
|
@ -762,10 +766,10 @@ proc evalMagicOrCall(c: PEvalContext, n: PNode): PNode =
|
||||||
result = evalAux(c, n.sons[1], {efLValue})
|
result = evalAux(c, n.sons[1], {efLValue})
|
||||||
if isSpecial(result): return
|
if isSpecial(result): return
|
||||||
var a = result
|
var a = result
|
||||||
result = evalAux(c, n.sons[2], {})
|
result = evalAux(c, n.sons[2], {efLValue})
|
||||||
if isSpecial(result): return
|
if isSpecial(result): return
|
||||||
var b = result
|
var b = result
|
||||||
result = evalAux(c, n.sons[3], {})
|
result = evalAux(c, n.sons[3], {efLValue})
|
||||||
if isSpecial(result): return
|
if isSpecial(result): return
|
||||||
for i in countup(0, int(getOrdValue(result)) - 1):
|
for i in countup(0, int(getOrdValue(result)) - 1):
|
||||||
delSon(a, int(getOrdValue(b)))
|
delSon(a, int(getOrdValue(b)))
|
||||||
|
|
@ -793,7 +797,7 @@ proc evalMagicOrCall(c: PEvalContext, n: PNode): PNode =
|
||||||
of nkFloatLit..nkFloat64Lit: result.floatVal = a.floatVal
|
of nkFloatLit..nkFloat64Lit: result.floatVal = a.floatVal
|
||||||
else: InternalError(n.info, "no float value")
|
else: InternalError(n.info, "no float value")
|
||||||
of mNSymbol:
|
of mNSymbol:
|
||||||
result = evalAux(c, n.sons[1], {})
|
result = evalAux(c, n.sons[1], {efLValue})
|
||||||
if isSpecial(result): return
|
if isSpecial(result): return
|
||||||
if result.kind != nkSym: InternalError(n.info, "no symbol")
|
if result.kind != nkSym: InternalError(n.info, "no symbol")
|
||||||
of mNIdent:
|
of mNIdent:
|
||||||
|
|
@ -829,7 +833,7 @@ proc evalMagicOrCall(c: PEvalContext, n: PNode): PNode =
|
||||||
result = evalAux(c, n.sons[1], {efLValue})
|
result = evalAux(c, n.sons[1], {efLValue})
|
||||||
if isSpecial(result): return
|
if isSpecial(result): return
|
||||||
var a = result
|
var a = result
|
||||||
result = evalAux(c, n.sons[2], {})
|
result = evalAux(c, n.sons[2], {efLValue})
|
||||||
if isSpecial(result): return
|
if isSpecial(result): return
|
||||||
a.sym = result.sym # XXX: exception handling?
|
a.sym = result.sym # XXX: exception handling?
|
||||||
result = emptyNode
|
result = emptyNode
|
||||||
|
|
@ -837,7 +841,7 @@ proc evalMagicOrCall(c: PEvalContext, n: PNode): PNode =
|
||||||
result = evalAux(c, n.sons[1], {efLValue})
|
result = evalAux(c, n.sons[1], {efLValue})
|
||||||
if isSpecial(result): return
|
if isSpecial(result): return
|
||||||
var a = result
|
var a = result
|
||||||
result = evalAux(c, n.sons[2], {})
|
result = evalAux(c, n.sons[2], {efLValue})
|
||||||
if isSpecial(result): return
|
if isSpecial(result): return
|
||||||
a.ident = result.ident # XXX: exception handling?
|
a.ident = result.ident # XXX: exception handling?
|
||||||
result = emptyNode
|
result = emptyNode
|
||||||
|
|
@ -845,7 +849,7 @@ proc evalMagicOrCall(c: PEvalContext, n: PNode): PNode =
|
||||||
result = evalAux(c, n.sons[1], {efLValue})
|
result = evalAux(c, n.sons[1], {efLValue})
|
||||||
if isSpecial(result): return
|
if isSpecial(result): return
|
||||||
var a = result
|
var a = result
|
||||||
result = evalAux(c, n.sons[2], {})
|
result = evalAux(c, n.sons[2], {efLValue})
|
||||||
if isSpecial(result): return
|
if isSpecial(result): return
|
||||||
a.typ = result.typ # XXX: exception handling?
|
a.typ = result.typ # XXX: exception handling?
|
||||||
result = emptyNode
|
result = emptyNode
|
||||||
|
|
@ -861,7 +865,7 @@ proc evalMagicOrCall(c: PEvalContext, n: PNode): PNode =
|
||||||
result = evalAux(c, n.sons[1], {})
|
result = evalAux(c, n.sons[1], {})
|
||||||
if isSpecial(result): return
|
if isSpecial(result): return
|
||||||
var k = getOrdValue(result)
|
var k = getOrdValue(result)
|
||||||
result = evalAux(c, n.sons[2], {})
|
result = evalAux(c, n.sons[2], {efLValue})
|
||||||
if result.kind == nkExceptBranch: return
|
if result.kind == nkExceptBranch: return
|
||||||
var a = result
|
var a = result
|
||||||
if (k < 0) or (k > ord(high(TNodeKind))):
|
if (k < 0) or (k > ord(high(TNodeKind))):
|
||||||
|
|
@ -869,11 +873,11 @@ proc evalMagicOrCall(c: PEvalContext, n: PNode): PNode =
|
||||||
result = newNodeI(TNodeKind(int(k)),
|
result = newNodeI(TNodeKind(int(k)),
|
||||||
if a.kind == nkNilLit: n.info else: a.info)
|
if a.kind == nkNilLit: n.info else: a.info)
|
||||||
of mNCopyNimNode:
|
of mNCopyNimNode:
|
||||||
result = evalAux(c, n.sons[1], {})
|
result = evalAux(c, n.sons[1], {efLValue})
|
||||||
if isSpecial(result): return
|
if isSpecial(result): return
|
||||||
result = copyNode(result)
|
result = copyNode(result)
|
||||||
of mNCopyNimTree:
|
of mNCopyNimTree:
|
||||||
result = evalAux(c, n.sons[1], {})
|
result = evalAux(c, n.sons[1], {efLValue})
|
||||||
if isSpecial(result): return
|
if isSpecial(result): return
|
||||||
result = copyTree(result)
|
result = copyTree(result)
|
||||||
of mStrToIdent:
|
of mStrToIdent:
|
||||||
|
|
@ -902,10 +906,10 @@ proc evalMagicOrCall(c: PEvalContext, n: PNode): PNode =
|
||||||
if (a.kind == nkIdent) and (b.kind == nkIdent):
|
if (a.kind == nkIdent) and (b.kind == nkIdent):
|
||||||
if a.ident.id == b.ident.id: result.intVal = 1
|
if a.ident.id == b.ident.id: result.intVal = 1
|
||||||
of mEqNimrodNode:
|
of mEqNimrodNode:
|
||||||
result = evalAux(c, n.sons[1], {})
|
result = evalAux(c, n.sons[1], {efLValue})
|
||||||
if isSpecial(result): return
|
if isSpecial(result): return
|
||||||
var a = result
|
var a = result
|
||||||
result = evalAux(c, n.sons[2], {})
|
result = evalAux(c, n.sons[2], {efLValue})
|
||||||
if isSpecial(result): return
|
if isSpecial(result): return
|
||||||
var b = result
|
var b = result
|
||||||
result = newNodeIT(nkIntLit, n.info, n.typ)
|
result = newNodeIT(nkIntLit, n.info, n.typ)
|
||||||
|
|
@ -966,16 +970,18 @@ proc evalAux(c: PEvalContext, n: PNode, flags: TEvalFlags): PNode =
|
||||||
of nkCall, nkHiddenCallConv, nkMacroStmt, nkCommand, nkCallStrLit:
|
of nkCall, nkHiddenCallConv, nkMacroStmt, nkCommand, nkCallStrLit:
|
||||||
result = evalMagicOrCall(c, n)
|
result = evalMagicOrCall(c, n)
|
||||||
of nkCurly, nkBracket, nkRange:
|
of nkCurly, nkBracket, nkRange:
|
||||||
|
# flags need to be passed here for mNAddMultiple :-(
|
||||||
|
# XXX this is not correct in every case!
|
||||||
var a = copyNode(n)
|
var a = copyNode(n)
|
||||||
for i in countup(0, sonsLen(n) - 1):
|
for i in countup(0, sonsLen(n) - 1):
|
||||||
result = evalAux(c, n.sons[i], {})
|
result = evalAux(c, n.sons[i], flags)
|
||||||
if isSpecial(result): return
|
if isSpecial(result): return
|
||||||
addSon(a, result)
|
addSon(a, result)
|
||||||
result = a
|
result = a
|
||||||
of nkPar:
|
of nkPar:
|
||||||
var a = copyTree(n)
|
var a = copyTree(n)
|
||||||
for i in countup(0, sonsLen(n) - 1):
|
for i in countup(0, sonsLen(n) - 1):
|
||||||
result = evalAux(c, n.sons[i].sons[1], {})
|
result = evalAux(c, n.sons[i].sons[1], flags)
|
||||||
if isSpecial(result): return
|
if isSpecial(result): return
|
||||||
a.sons[i].sons[1] = result
|
a.sons[i].sons[1] = result
|
||||||
result = a
|
result = a
|
||||||
|
|
|
||||||
|
|
@ -283,7 +283,7 @@ proc NameToCC(name: string): TSystemCC =
|
||||||
result = ccNone
|
result = ccNone
|
||||||
|
|
||||||
proc addOpt(dest: var string, src: string) =
|
proc addOpt(dest: var string, src: string) =
|
||||||
if (len(dest) == 0) or (dest[len(dest) - 1 + 0] != ' '): add(dest, " ")
|
if len(dest) == 0 or dest[len(dest) - 1 + 0] != ' ': add(dest, " ")
|
||||||
add(dest, src)
|
add(dest, src)
|
||||||
|
|
||||||
proc addCompileOption(option: string) =
|
proc addCompileOption(option: string) =
|
||||||
|
|
@ -308,7 +308,7 @@ proc addFileToLink(filename: string) =
|
||||||
|
|
||||||
proc execExternalProgram(cmd: string) =
|
proc execExternalProgram(cmd: string) =
|
||||||
if (optListCmd in gGlobalOptions) or (gVerbosity > 0): MessageOut(cmd)
|
if (optListCmd in gGlobalOptions) or (gVerbosity > 0): MessageOut(cmd)
|
||||||
if execCmd(cmd) != 0: rawMessage(errExecutionOfProgramFailed)
|
if execCmd(cmd) != 0: rawMessage(errExecutionOfProgramFailed, "")
|
||||||
|
|
||||||
proc generateScript(projectFile: string, script: PRope) =
|
proc generateScript(projectFile: string, script: PRope) =
|
||||||
var (dir, name, ext) = splitFile(projectFile)
|
var (dir, name, ext) = splitFile(projectFile)
|
||||||
|
|
@ -425,7 +425,7 @@ proc CallCCompiler(projectfile: string) =
|
||||||
else:
|
else:
|
||||||
res = execProcesses(cmds, {poUseShell, poParentStreams},
|
res = execProcesses(cmds, {poUseShell, poParentStreams},
|
||||||
gNumberOfProcessors)
|
gNumberOfProcessors)
|
||||||
if res != 0: rawMessage(errExecutionOfProgramFailed)
|
if res != 0: rawMessage(errExecutionOfProgramFailed, [])
|
||||||
if not (optNoLinking in gGlobalOptions):
|
if not (optNoLinking in gGlobalOptions):
|
||||||
# call the linker:
|
# call the linker:
|
||||||
var linkerExe = getConfigVar(cc[c].name & ".linkerexe")
|
var linkerExe = getConfigVar(cc[c].name & ".linkerexe")
|
||||||
|
|
|
||||||
|
|
@ -323,7 +323,7 @@ const # this format is understood by many text editors: it is the same that
|
||||||
RawHintFormat* = "Hint: $1"
|
RawHintFormat* = "Hint: $1"
|
||||||
|
|
||||||
proc MessageOut*(s: string)
|
proc MessageOut*(s: string)
|
||||||
proc rawMessage*(msg: TMsgKind, arg: string = "")
|
proc rawMessage*(msg: TMsgKind, arg: string)
|
||||||
proc rawMessage*(msg: TMsgKind, args: openarray[string])
|
proc rawMessage*(msg: TMsgKind, args: openarray[string])
|
||||||
proc liMessage*(info: TLineInfo, msg: TMsgKind, arg: string = "")
|
proc liMessage*(info: TLineInfo, msg: TMsgKind, arg: string = "")
|
||||||
proc InternalError*(info: TLineInfo, errMsg: string)
|
proc InternalError*(info: TLineInfo, errMsg: string)
|
||||||
|
|
@ -475,7 +475,7 @@ proc rawMessage(msg: TMsgKind, args: openarray[string]) =
|
||||||
MessageOut(`%`(frmt, `%`(msgKindToString(msg), args)))
|
MessageOut(`%`(frmt, `%`(msgKindToString(msg), args)))
|
||||||
handleError(msg)
|
handleError(msg)
|
||||||
|
|
||||||
proc rawMessage(msg: TMsgKind, arg: string = "") =
|
proc rawMessage(msg: TMsgKind, arg: string) =
|
||||||
rawMessage(msg, [arg])
|
rawMessage(msg, [arg])
|
||||||
|
|
||||||
proc liMessage(info: TLineInfo, msg: TMsgKind, arg: string = "") =
|
proc liMessage(info: TLineInfo, msg: TMsgKind, arg: string = "") =
|
||||||
|
|
|
||||||
|
|
@ -72,13 +72,18 @@ Files: "lib/wrappers/x11/*.nim"
|
||||||
Files: "lib/wrappers/zip/*.nim"
|
Files: "lib/wrappers/zip/*.nim"
|
||||||
Files: "lib/wrappers/zip/libzip_all.c"
|
Files: "lib/wrappers/zip/libzip_all.c"
|
||||||
|
|
||||||
Files: "lib/newwrap/*.nim"
|
Files: "lib/oldwrappers/*.nim"
|
||||||
|
|
||||||
Files: "lib/newwrap/cairo/*.nim"
|
Files: "lib/oldwrappers/cairo/*.nim"
|
||||||
Files: "lib/newwrap/gtk/*.nim"
|
Files: "lib/oldwrappers/gtk/*.nim"
|
||||||
Files: "lib/newwrap/lua/*.nim"
|
Files: "lib/oldwrappers/lua/*.nim"
|
||||||
Files: "lib/newwrap/sdl/*.nim"
|
Files: "lib/oldwrappers/opengl/*.nim"
|
||||||
Files: "lib/newwrap/x11/*.nim"
|
Files: "lib/oldwrappers/pcre/*.nim"
|
||||||
|
Files: "lib/oldwrappers/pcre/pcre_all.c"
|
||||||
|
Files: "lib/oldwrappers/sdl/*.nim"
|
||||||
|
Files: "lib/oldwrappers/x11/*.nim"
|
||||||
|
Files: "lib/oldwrappers/zip/*.nim"
|
||||||
|
Files: "lib/oldwrappers/zip/libzip_all.c"
|
||||||
|
|
||||||
Files: "lib/windows/*.nim"
|
Files: "lib/windows/*.nim"
|
||||||
Files: "lib/posix/*.nim"
|
Files: "lib/posix/*.nim"
|
||||||
|
|
@ -90,7 +95,9 @@ Files: "tests/*.html"
|
||||||
Files: "tests/*.txt"
|
Files: "tests/*.txt"
|
||||||
Files: "tests/*.cfg"
|
Files: "tests/*.cfg"
|
||||||
Files: "tests/*.tmpl"
|
Files: "tests/*.tmpl"
|
||||||
Files: "tests/gtk/*.nim"
|
Files: "tests/accept/run/*.nim"
|
||||||
|
Files: "tests/accept/compile/*.nim"
|
||||||
|
Files: "tests/reject/*.nim"
|
||||||
|
|
||||||
Files: "examples/*.nim"
|
Files: "examples/*.nim"
|
||||||
Files: "examples/*.html"
|
Files: "examples/*.html"
|
||||||
|
|
|
||||||
|
|
@ -42,7 +42,7 @@ proc ProcessCmdLine(pass: TCmdLinePass, command, filename: var string) =
|
||||||
if pass == passCmd2:
|
if pass == passCmd2:
|
||||||
arguments = cmdLineRest(p)
|
arguments = cmdLineRest(p)
|
||||||
if not (optRun in gGlobalOptions) and (arguments != ""):
|
if not (optRun in gGlobalOptions) and (arguments != ""):
|
||||||
rawMessage(errArgsNeedRunOption)
|
rawMessage(errArgsNeedRunOption, [])
|
||||||
|
|
||||||
proc HandleCmdLine() =
|
proc HandleCmdLine() =
|
||||||
var start = getTime()
|
var start = getTime()
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,6 @@ const
|
||||||
defaultAsmMarkerSymbol* = '!'
|
defaultAsmMarkerSymbol* = '!'
|
||||||
VersionMajor* = 0
|
VersionMajor* = 0
|
||||||
VersionMinor* = 8
|
VersionMinor* = 8
|
||||||
VersionPatch* = 7
|
VersionPatch* = 8
|
||||||
VersionAsString* = $VersionMajor & "." & $VersionMinor & "." & $VersionPatch
|
VersionAsString* = $VersionMajor & "." & $VersionMinor & "." & $VersionPatch
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
# The Nimrod Compiler
|
# The Nimrod Compiler
|
||||||
# (c) Copyright 2009 Andreas Rumpf
|
# (c) Copyright 2010 Andreas Rumpf
|
||||||
#
|
#
|
||||||
# See the file "copying.txt", included in this
|
# See the file "copying.txt", included in this
|
||||||
# distribution, for details about the copyright.
|
# distribution, for details about the copyright.
|
||||||
|
|
@ -18,36 +18,16 @@ import
|
||||||
type
|
type
|
||||||
TPassContext* = object of TObject # the pass's context
|
TPassContext* = object of TObject # the pass's context
|
||||||
PPassContext* = ref TPassContext
|
PPassContext* = ref TPassContext
|
||||||
TPass* = tuple[open: proc (module: PSym, filename: string): PPassContext,
|
TPass* = tuple[
|
||||||
openCached: proc (module: PSym, filename: string, rd: PRodReader): PPassContext,
|
open: proc (module: PSym, filename: string): PPassContext,
|
||||||
|
openCached: proc (module: PSym, filename: string,
|
||||||
|
rd: PRodReader): PPassContext,
|
||||||
close: proc (p: PPassContext, n: PNode): PNode,
|
close: proc (p: PPassContext, n: PNode): PNode,
|
||||||
process: proc (p: PPassContext, topLevelStmt: PNode): PNode] # a
|
process: proc (p: PPassContext, topLevelStmt: PNode): PNode]
|
||||||
# pass is a
|
|
||||||
# tuple of
|
# a pass is a tuple of procedure vars ``TPass.close`` may produce additional
|
||||||
# procedure
|
# nodes. These are passed to the other close procedures.
|
||||||
# vars
|
# This mechanism is needed for the instantiation of generics.
|
||||||
#
|
|
||||||
# ``TPass.close``
|
|
||||||
# may
|
|
||||||
# produce
|
|
||||||
# additional
|
|
||||||
# nodes.
|
|
||||||
# These
|
|
||||||
# are
|
|
||||||
# passed to
|
|
||||||
# the
|
|
||||||
# other
|
|
||||||
#
|
|
||||||
# close
|
|
||||||
# procedures.
|
|
||||||
# This
|
|
||||||
# mechanism is
|
|
||||||
# needed
|
|
||||||
# for
|
|
||||||
# the
|
|
||||||
# instantiation of
|
|
||||||
#
|
|
||||||
# generics.
|
|
||||||
|
|
||||||
proc registerPass*(p: TPass)
|
proc registerPass*(p: TPass)
|
||||||
proc initPass*(p: var TPass)
|
proc initPass*(p: var TPass)
|
||||||
|
|
@ -62,7 +42,8 @@ proc astNeeded*(s: PSym): bool
|
||||||
# needs to be stored. The passes manager frees s.sons[codePos] when
|
# needs to be stored. The passes manager frees s.sons[codePos] when
|
||||||
# appropriate to free the procedure body's memory. This is important
|
# appropriate to free the procedure body's memory. This is important
|
||||||
# to keep memory usage down.
|
# to keep memory usage down.
|
||||||
# the semantic checker needs these:
|
|
||||||
|
# the semantic checker needs these:
|
||||||
var
|
var
|
||||||
gImportModule*: proc (filename: string): PSym
|
gImportModule*: proc (filename: string): PSym
|
||||||
gIncludeFile*: proc (filename: string): PNode
|
gIncludeFile*: proc (filename: string): PNode
|
||||||
|
|
@ -105,29 +86,25 @@ proc openPassesCached(a: var TPassContextArray, module: PSym, filename: string,
|
||||||
a[i] = nil
|
a[i] = nil
|
||||||
|
|
||||||
proc closePasses(a: var TPassContextArray) =
|
proc closePasses(a: var TPassContextArray) =
|
||||||
var m: PNode
|
var m: PNode = nil
|
||||||
m = nil
|
|
||||||
for i in countup(0, gPassesLen - 1):
|
for i in countup(0, gPassesLen - 1):
|
||||||
if not isNil(gPasses[i].close): m = gPasses[i].close(a[i], m)
|
if not isNil(gPasses[i].close): m = gPasses[i].close(a[i], m)
|
||||||
a[i] = nil # free the memory here
|
a[i] = nil # free the memory here
|
||||||
|
|
||||||
proc processTopLevelStmt(n: PNode, a: var TPassContextArray) =
|
proc processTopLevelStmt(n: PNode, a: var TPassContextArray) =
|
||||||
var m: PNode
|
|
||||||
# this implements the code transformation pipeline
|
# this implements the code transformation pipeline
|
||||||
m = n
|
var m = n
|
||||||
for i in countup(0, gPassesLen - 1):
|
for i in countup(0, gPassesLen - 1):
|
||||||
if not isNil(gPasses[i].process): m = gPasses[i].process(a[i], m)
|
if not isNil(gPasses[i].process): m = gPasses[i].process(a[i], m)
|
||||||
|
|
||||||
proc processTopLevelStmtCached(n: PNode, a: var TPassContextArray) =
|
proc processTopLevelStmtCached(n: PNode, a: var TPassContextArray) =
|
||||||
var m: PNode
|
|
||||||
# this implements the code transformation pipeline
|
# this implements the code transformation pipeline
|
||||||
m = n
|
var m = n
|
||||||
for i in countup(0, gPassesLen - 1):
|
for i in countup(0, gPassesLen - 1):
|
||||||
if not isNil(gPasses[i].openCached): m = gPasses[i].process(a[i], m)
|
if not isNil(gPasses[i].openCached): m = gPasses[i].process(a[i], m)
|
||||||
|
|
||||||
proc closePassesCached(a: var TPassContextArray) =
|
proc closePassesCached(a: var TPassContextArray) =
|
||||||
var m: PNode
|
var m: PNode = nil
|
||||||
m = nil
|
|
||||||
for i in countup(0, gPassesLen - 1):
|
for i in countup(0, gPassesLen - 1):
|
||||||
if not isNil(gPasses[i].openCached) and not isNil(gPasses[i].close):
|
if not isNil(gPasses[i].openCached) and not isNil(gPasses[i].close):
|
||||||
m = gPasses[i].close(a[i], m)
|
m = gPasses[i].close(a[i], m)
|
||||||
|
|
@ -157,7 +134,8 @@ proc processModule(module: PSym, filename: string, stream: PLLStream,
|
||||||
processTopLevelStmt(n, a)
|
processTopLevelStmt(n, a)
|
||||||
closeParsers(p)
|
closeParsers(p)
|
||||||
if s.kind != llsStdIn: break
|
if s.kind != llsStdIn: break
|
||||||
closePasses(a) # id synchronization point for more consistent code generation:
|
closePasses(a)
|
||||||
|
# id synchronization point for more consistent code generation:
|
||||||
IDsynchronizationPoint(1000)
|
IDsynchronizationPoint(1000)
|
||||||
else:
|
else:
|
||||||
openPassesCached(a, module, filename, rd)
|
openPassesCached(a, module, filename, rd)
|
||||||
|
|
|
||||||
|
|
@ -388,6 +388,11 @@ proc analyseIfAddressTakenInCall(c: PContext, n: PNode) =
|
||||||
checkMinSonsLen(n, 1)
|
checkMinSonsLen(n, 1)
|
||||||
var t = n.sons[0].typ
|
var t = n.sons[0].typ
|
||||||
if (n.sons[0].kind == nkSym) and (n.sons[0].sym.magic in FakeVarParams):
|
if (n.sons[0].kind == nkSym) and (n.sons[0].sym.magic in FakeVarParams):
|
||||||
|
# BUGFIX: check for L-Value still needs to be done for the arguments!
|
||||||
|
for i in countup(1, sonsLen(n) - 1):
|
||||||
|
if i < sonsLen(t) and skipTypes(t.sons[i], abstractInst).kind == tyVar:
|
||||||
|
if isAssignable(n.sons[i]) != arLValue:
|
||||||
|
liMessage(n.sons[i].info, errVarForOutParamNeeded)
|
||||||
return
|
return
|
||||||
for i in countup(1, sonsLen(n) - 1):
|
for i in countup(1, sonsLen(n) - 1):
|
||||||
if (i < sonsLen(t)) and
|
if (i < sonsLen(t)) and
|
||||||
|
|
@ -781,7 +786,7 @@ proc semArrayAccess(c: PContext, n: PNode, flags: TExprFlags): PNode =
|
||||||
|
|
||||||
proc semIfExpr(c: PContext, n: PNode): PNode =
|
proc semIfExpr(c: PContext, n: PNode): PNode =
|
||||||
result = n
|
result = n
|
||||||
checkSonsLen(n, 2)
|
checkMinSonsLen(n, 2)
|
||||||
var typ: PType = nil
|
var typ: PType = nil
|
||||||
for i in countup(0, sonsLen(n) - 1):
|
for i in countup(0, sonsLen(n) - 1):
|
||||||
var it = n.sons[i]
|
var it = n.sons[i]
|
||||||
|
|
|
||||||
|
|
@ -117,29 +117,26 @@ proc concreteType(mapping: TIdTable, t: PType): PType =
|
||||||
result = t # Note: empty is valid here
|
result = t # Note: empty is valid here
|
||||||
|
|
||||||
proc handleRange(f, a: PType, min, max: TTypeKind): TTypeRelation =
|
proc handleRange(f, a: PType, min, max: TTypeKind): TTypeRelation =
|
||||||
var k: TTypeKind
|
|
||||||
if a.kind == f.kind:
|
if a.kind == f.kind:
|
||||||
result = isEqual
|
result = isEqual
|
||||||
else:
|
else:
|
||||||
k = skipTypes(a, {tyRange}).kind
|
var k = skipTypes(a, {tyRange}).kind
|
||||||
if k == f.kind: result = isSubtype
|
if k == f.kind: result = isSubtype
|
||||||
elif (f.kind == tyInt) and (k in {tyInt..tyInt32}): result = isIntConv
|
elif (f.kind == tyInt) and (k in {tyInt..tyInt32}): result = isIntConv
|
||||||
elif (k >= min) and (k <= max): result = isConvertible
|
elif (k >= min) and (k <= max): result = isConvertible
|
||||||
else: result = isNone
|
else: result = isNone
|
||||||
|
|
||||||
proc handleFloatRange(f, a: PType): TTypeRelation =
|
proc handleFloatRange(f, a: PType): TTypeRelation =
|
||||||
var k: TTypeKind
|
|
||||||
if a.kind == f.kind:
|
if a.kind == f.kind:
|
||||||
result = isEqual
|
result = isEqual
|
||||||
else:
|
else:
|
||||||
k = skipTypes(a, {tyRange}).kind
|
var k = skipTypes(a, {tyRange}).kind
|
||||||
if k == f.kind: result = isSubtype
|
if k == f.kind: result = isSubtype
|
||||||
elif (k >= tyFloat) and (k <= tyFloat128): result = isConvertible
|
elif (k >= tyFloat) and (k <= tyFloat128): result = isConvertible
|
||||||
else: result = isNone
|
else: result = isNone
|
||||||
|
|
||||||
proc isObjectSubtype(a, f: PType): bool =
|
proc isObjectSubtype(a, f: PType): bool =
|
||||||
var t: PType
|
var t = a
|
||||||
t = a
|
|
||||||
while (t != nil) and (t.id != f.id): t = base(t)
|
while (t != nil) and (t.id != f.id): t = base(t)
|
||||||
result = t != nil
|
result = t != nil
|
||||||
|
|
||||||
|
|
@ -148,14 +145,11 @@ proc minRel(a, b: TTypeRelation): TTypeRelation =
|
||||||
else: result = b
|
else: result = b
|
||||||
|
|
||||||
proc tupleRel(mapping: var TIdTable, f, a: PType): TTypeRelation =
|
proc tupleRel(mapping: var TIdTable, f, a: PType): TTypeRelation =
|
||||||
var
|
|
||||||
x, y: PSym
|
|
||||||
m: TTypeRelation
|
|
||||||
result = isNone
|
result = isNone
|
||||||
if sonsLen(a) == sonsLen(f):
|
if sonsLen(a) == sonsLen(f):
|
||||||
result = isEqual
|
result = isEqual
|
||||||
for i in countup(0, sonsLen(f) - 1):
|
for i in countup(0, sonsLen(f) - 1):
|
||||||
m = typeRel(mapping, f.sons[i], a.sons[i])
|
var m = typeRel(mapping, f.sons[i], a.sons[i])
|
||||||
if m < isSubtype:
|
if m < isSubtype:
|
||||||
return isNone
|
return isNone
|
||||||
result = minRel(result, m)
|
result = minRel(result, m)
|
||||||
|
|
@ -164,8 +158,8 @@ proc tupleRel(mapping: var TIdTable, f, a: PType): TTypeRelation =
|
||||||
# check field names:
|
# check field names:
|
||||||
if f.n.sons[i].kind != nkSym: InternalError(f.n.info, "tupleRel")
|
if f.n.sons[i].kind != nkSym: InternalError(f.n.info, "tupleRel")
|
||||||
if a.n.sons[i].kind != nkSym: InternalError(a.n.info, "tupleRel")
|
if a.n.sons[i].kind != nkSym: InternalError(a.n.info, "tupleRel")
|
||||||
x = f.n.sons[i].sym
|
var x = f.n.sons[i].sym
|
||||||
y = a.n.sons[i].sym
|
var y = a.n.sons[i].sym
|
||||||
if x.name.id != y.name.id:
|
if x.name.id != y.name.id:
|
||||||
return isNone
|
return isNone
|
||||||
|
|
||||||
|
|
@ -438,8 +432,7 @@ proc typeRel(mapping: var TIdTable, f, a: PType): TTypeRelation =
|
||||||
case a.kind
|
case a.kind
|
||||||
of tyExpr, tyStmt, tyTypeDesc: result = isGeneric
|
of tyExpr, tyStmt, tyTypeDesc: result = isGeneric
|
||||||
of tyNil: result = isSubtype
|
of tyNil: result = isSubtype
|
||||||
else:
|
else: nil
|
||||||
nil
|
|
||||||
else: internalError("typeRel(" & $f.kind & ')')
|
else: internalError("typeRel(" & $f.kind & ')')
|
||||||
|
|
||||||
proc cmpTypes(f, a: PType): TTypeRelation =
|
proc cmpTypes(f, a: PType): TTypeRelation =
|
||||||
|
|
@ -522,10 +515,6 @@ proc ParamTypesMatchAux(c: PContext, m: var TCandidate, f, a: PType,
|
||||||
|
|
||||||
proc ParamTypesMatch(c: PContext, m: var TCandidate, f, a: PType,
|
proc ParamTypesMatch(c: PContext, m: var TCandidate, f, a: PType,
|
||||||
arg: PNode): PNode =
|
arg: PNode): PNode =
|
||||||
var
|
|
||||||
cmp, best: int
|
|
||||||
x, y, z: TCandidate
|
|
||||||
r: TTypeRelation
|
|
||||||
if (arg == nil) or (arg.kind != nkSymChoice):
|
if (arg == nil) or (arg.kind != nkSymChoice):
|
||||||
result = ParamTypesMatchAux(c, m, f, a, arg)
|
result = ParamTypesMatchAux(c, m, f, a, arg)
|
||||||
else:
|
else:
|
||||||
|
|
@ -533,18 +522,19 @@ proc ParamTypesMatch(c: PContext, m: var TCandidate, f, a: PType,
|
||||||
# incorrect to simply use the first fitting match. However, to implement
|
# incorrect to simply use the first fitting match. However, to implement
|
||||||
# this correctly is inefficient. We have to copy `m` here to be able to
|
# this correctly is inefficient. We have to copy `m` here to be able to
|
||||||
# roll back the side effects of the unification algorithm.
|
# roll back the side effects of the unification algorithm.
|
||||||
|
var x, y, z: TCandidate
|
||||||
initCandidate(x, m.callee)
|
initCandidate(x, m.callee)
|
||||||
initCandidate(y, m.callee)
|
initCandidate(y, m.callee)
|
||||||
initCandidate(z, m.callee)
|
initCandidate(z, m.callee)
|
||||||
x.calleeSym = m.calleeSym
|
x.calleeSym = m.calleeSym
|
||||||
y.calleeSym = m.calleeSym
|
y.calleeSym = m.calleeSym
|
||||||
z.calleeSym = m.calleeSym
|
z.calleeSym = m.calleeSym
|
||||||
best = - 1
|
var best = - 1
|
||||||
for i in countup(0, sonsLen(arg) - 1):
|
for i in countup(0, sonsLen(arg) - 1):
|
||||||
# iterators are not first class yet, so ignore them
|
# iterators are not first class yet, so ignore them
|
||||||
if arg.sons[i].sym.kind in {skProc, skMethod, skConverter}:
|
if arg.sons[i].sym.kind in {skProc, skMethod, skConverter}:
|
||||||
copyCandidate(z, m)
|
copyCandidate(z, m)
|
||||||
r = typeRel(z.bindings, f, arg.sons[i].typ)
|
var r = typeRel(z.bindings, f, arg.sons[i].typ)
|
||||||
if r != isNone:
|
if r != isNone:
|
||||||
case x.state
|
case x.state
|
||||||
of csEmpty, csNoMatch:
|
of csEmpty, csNoMatch:
|
||||||
|
|
@ -552,7 +542,7 @@ proc ParamTypesMatch(c: PContext, m: var TCandidate, f, a: PType,
|
||||||
best = i
|
best = i
|
||||||
x.state = csMatch
|
x.state = csMatch
|
||||||
of csMatch:
|
of csMatch:
|
||||||
cmp = cmpCandidates(x, z)
|
var cmp = cmpCandidates(x, z)
|
||||||
if cmp < 0:
|
if cmp < 0:
|
||||||
best = i
|
best = i
|
||||||
x = z
|
x = z
|
||||||
|
|
@ -658,7 +648,7 @@ proc matches(c: PContext, n: PNode, m: var TCandidate) =
|
||||||
return
|
return
|
||||||
m.baseTypeMatch = false
|
m.baseTypeMatch = false
|
||||||
var arg = ParamTypesMatch(c, m, formal.typ, n.sons[a].typ, n.sons[a])
|
var arg = ParamTypesMatch(c, m, formal.typ, n.sons[a].typ, n.sons[a])
|
||||||
if (arg == nil):
|
if arg == nil:
|
||||||
m.state = csNoMatch
|
m.state = csNoMatch
|
||||||
return
|
return
|
||||||
if m.baseTypeMatch:
|
if m.baseTypeMatch:
|
||||||
|
|
@ -677,6 +667,11 @@ proc matches(c: PContext, n: PNode, m: var TCandidate) =
|
||||||
formal = m.callee.n.sons[f].sym
|
formal = m.callee.n.sons[f].sym
|
||||||
if not IntSetContainsOrIncl(marker, formal.position):
|
if not IntSetContainsOrIncl(marker, formal.position):
|
||||||
if formal.ast == nil:
|
if formal.ast == nil:
|
||||||
|
if formal.typ.kind == tyOpenArray:
|
||||||
|
container = newNodeI(nkBracket, n.info)
|
||||||
|
addSon(m.call, implicitConv(nkHiddenStdConv, formal.typ,
|
||||||
|
container, m, c))
|
||||||
|
else:
|
||||||
# no default value
|
# no default value
|
||||||
m.state = csNoMatch
|
m.state = csNoMatch
|
||||||
break
|
break
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
# The Nimrod Compiler
|
# The Nimrod Compiler
|
||||||
# (c) Copyright 2009 Andreas Rumpf
|
# (c) Copyright 2010 Andreas Rumpf
|
||||||
#
|
#
|
||||||
# See the file "copying.txt", included in this
|
# See the file "copying.txt", included in this
|
||||||
# distribution, for details about the copyright.
|
# distribution, for details about the copyright.
|
||||||
|
|
@ -142,9 +142,9 @@ proc applyFilter(p: var TParsers, n: PNode, filename: string, stdin: PLLStream):
|
||||||
result = filterReplace(stdin, filename, n)
|
result = filterReplace(stdin, filename, n)
|
||||||
if f != filtNone:
|
if f != filtNone:
|
||||||
if gVerbosity >= 2:
|
if gVerbosity >= 2:
|
||||||
rawMessage(hintCodeBegin)
|
rawMessage(hintCodeBegin, [])
|
||||||
messageOut(result.s)
|
messageOut(result.s)
|
||||||
rawMessage(hintCodeEnd)
|
rawMessage(hintCodeEnd, [])
|
||||||
|
|
||||||
proc evalPipe(p: var TParsers, n: PNode, filename: string, start: PLLStream): PLLStream =
|
proc evalPipe(p: var TParsers, n: PNode, filename: string, start: PLLStream): PLLStream =
|
||||||
result = start
|
result = start
|
||||||
|
|
|
||||||
5
tests/accept/compile/tconvcolors.nim
Executable file
5
tests/accept/compile/tconvcolors.nim
Executable file
|
|
@ -0,0 +1,5 @@
|
||||||
|
|
||||||
|
import colors
|
||||||
|
|
||||||
|
echo int32(colWhite), 'A'
|
||||||
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
import dialogs, gtk2
|
import dialogs, gtk2
|
||||||
|
|
||||||
gtk_nimrod_init()
|
gtk2.nimrod_init()
|
||||||
|
|
||||||
var x = ChooseFilesToOpen(nil)
|
var x = ChooseFilesToOpen(nil)
|
||||||
for a in items(x):
|
for a in items(x):
|
||||||
|
|
|
||||||
|
|
@ -3,10 +3,10 @@ import
|
||||||
gtk2, glib2, atk, gdk2, gdk2pixbuf, libglade2, pango,
|
gtk2, glib2, atk, gdk2, gdk2pixbuf, libglade2, pango,
|
||||||
pangoutils
|
pangoutils
|
||||||
|
|
||||||
proc hello(widget: PGtkWidget, data: pointer) {.cdecl.} =
|
proc hello(widget: PWidget, data: pointer) {.cdecl.} =
|
||||||
write(stdout, "Hello World\n")
|
write(stdout, "Hello World\n")
|
||||||
|
|
||||||
proc delete_event(widget: PGtkWidget, event: PGdkEvent,
|
proc delete_event(widget: PWidget, event: PEvent,
|
||||||
data: pointer): bool {.cdecl.} =
|
data: pointer): bool {.cdecl.} =
|
||||||
# If you return FALSE in the "delete_event" signal handler,
|
# If you return FALSE in the "delete_event" signal handler,
|
||||||
# GTK will emit the "destroy" signal. Returning TRUE means
|
# GTK will emit the "destroy" signal. Returning TRUE means
|
||||||
|
|
@ -19,43 +19,33 @@ proc delete_event(widget: PGtkWidget, event: PGdkEvent,
|
||||||
return false
|
return false
|
||||||
|
|
||||||
# Another callback
|
# Another callback
|
||||||
proc destroy(widget: PGtkWidget, data: pointer) {.cdecl.} =
|
proc mydestroy(widget: PWidget, data: pointer) {.cdecl.} =
|
||||||
gtk_main_quit()
|
gtk2.main_quit()
|
||||||
|
|
||||||
proc main() =
|
proc mymain() =
|
||||||
# GtkWidget is the storage type for widgets
|
# GtkWidget is the storage type for widgets
|
||||||
var
|
gtk2.nimrod_init()
|
||||||
window: PGtkWindow
|
var window = window_new(gtk2.WINDOW_TOPLEVEL)
|
||||||
button: PGtkButton
|
|
||||||
|
|
||||||
gtk_nimrod_init()
|
|
||||||
window = GTK_WINDOW(gtk_window_new(GTK_WINDOW_TOPLEVEL))
|
|
||||||
discard g_signal_connect(window, "delete_event",
|
discard g_signal_connect(window, "delete_event",
|
||||||
Gcallback(delete_event), nil)
|
Gcallback(delete_event), nil)
|
||||||
discard g_signal_connect(window, "destroy", Gcallback(destroy), nil)
|
discard g_signal_connect(window, "destroy", Gcallback(mydestroy), nil)
|
||||||
# Sets the border width of the window.
|
# Sets the border width of the window.
|
||||||
gtk_container_set_border_width(window, 10)
|
set_border_width(window, 10)
|
||||||
|
|
||||||
# Creates a new button with the label "Hello World".
|
# Creates a new button with the label "Hello World".
|
||||||
button = GTK_BUTTON(gtk_button_new_with_label("Hello World"))
|
var button = button_new("Hello World")
|
||||||
|
|
||||||
discard g_signal_connect(button, "clicked", Gcallback(hello), nil)
|
discard g_signal_connect(button, "clicked", Gcallback(hello), nil)
|
||||||
|
|
||||||
# This will cause the window to be destroyed by calling
|
|
||||||
# gtk_widget_destroy(window) when "clicked". Again, the destroy
|
|
||||||
# signal could come from here, or the window manager.
|
|
||||||
discard g_signal_connect_swapped(button, "clicked",
|
|
||||||
Gcallback(gtk_widget_destroy), window)
|
|
||||||
|
|
||||||
# This packs the button into the window (a gtk container).
|
# This packs the button into the window (a gtk container).
|
||||||
gtk_container_add(window, button)
|
add(window, button)
|
||||||
|
|
||||||
# The final step is to display this newly created widget.
|
# The final step is to display this newly created widget.
|
||||||
gtk_widget_show(button)
|
show(button)
|
||||||
|
|
||||||
# and the window
|
# and the window
|
||||||
gtk_widget_show(window)
|
show(window)
|
||||||
|
|
||||||
gtk_main()
|
gtk2.main()
|
||||||
|
|
||||||
main()
|
mymain()
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@ proc splitText(txt: string): seq[string] # splits a text into several lines
|
||||||
# the comment continues here
|
# the comment continues here
|
||||||
# this is not easy to parse!
|
# this is not easy to parse!
|
||||||
|
|
||||||
proc anotherSplit(txt: string): list[string] =
|
proc anotherSplit(txt: string): seq[string] =
|
||||||
# the comment should belong to `anotherSplit`!
|
# the comment should belong to `anotherSplit`!
|
||||||
# another problem: comments are statements!
|
# another problem: comments are statements!
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,10 @@ import
|
||||||
cairowin32, cairoxlib,
|
cairowin32, cairoxlib,
|
||||||
odbcsql,
|
odbcsql,
|
||||||
gl, glut, glu, glx, glext, wingl,
|
gl, glut, glu, glx, glext, wingl,
|
||||||
lua, lualib, lauxlib, mysql, sqlite3, python, tcl
|
lua, lualib, lauxlib, mysql, sqlite3, python, tcl,
|
||||||
|
db_postgres, db_mysql, db_sqlite, ropes, sockets, browsers, httpserver,
|
||||||
|
httpclient, parseutils, unidecode, xmldom, xmldomparser, xmltree, xmlparser,
|
||||||
|
htmlparser, re, graphics, colors
|
||||||
|
|
||||||
when defined(linux):
|
when defined(linux):
|
||||||
import
|
import
|
||||||
|
|
|
||||||
7
tests/accept/compile/tnoargopenarray.nim
Normal file
7
tests/accept/compile/tnoargopenarray.nim
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
|
||||||
|
import db_sqlite
|
||||||
|
|
||||||
|
var db: TDbConn
|
||||||
|
Exec(db, sql"create table blabla()")
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -11,6 +11,7 @@ tbintree.nim;halloworld99110223
|
||||||
tbug499771.nim;TSubRange: 5 from 1 to 10
|
tbug499771.nim;TSubRange: 5 from 1 to 10
|
||||||
tbug511622.nim;3
|
tbug511622.nim;3
|
||||||
tcasestm.nim;ayyy
|
tcasestm.nim;ayyy
|
||||||
|
tcgbug.nim;
|
||||||
tclosure.nim;2 4 6 8 10
|
tclosure.nim;2 4 6 8 10
|
||||||
tcnstseq.nim;AngelikaAnneAnnaAnkaAnja
|
tcnstseq.nim;AngelikaAnneAnnaAnkaAnja
|
||||||
tconstr2.nim;69
|
tconstr2.nim;69
|
||||||
|
|
|
||||||
|
17
tests/accept/run/tcgbug.nim
Normal file
17
tests/accept/run/tcgbug.nim
Normal file
|
|
@ -0,0 +1,17 @@
|
||||||
|
|
||||||
|
type
|
||||||
|
TObj = object
|
||||||
|
x, y: int
|
||||||
|
PObj = ref TObj
|
||||||
|
|
||||||
|
proc p(a: PObj) =
|
||||||
|
a.x = 0
|
||||||
|
|
||||||
|
proc q(a: var PObj) =
|
||||||
|
a.p()
|
||||||
|
|
||||||
|
var
|
||||||
|
a: PObj
|
||||||
|
new(a)
|
||||||
|
q(a)
|
||||||
|
|
||||||
6
tests/accept/run/txmlgen.nim
Executable file
6
tests/accept/run/txmlgen.nim
Executable file
|
|
@ -0,0 +1,6 @@
|
||||||
|
import xmlgen
|
||||||
|
|
||||||
|
var nim = "Nimrod"
|
||||||
|
echo h1(a(href="http://force7.de/nimrod", nim))
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
|
|
||||||
import xmltree
|
import xmltree, strtabs
|
||||||
|
|
||||||
var x = <>a(href="nimrod.de", "www.nimrod-test.de")
|
var x = <>a(href="nimrod.de", newText("www.nimrod-test.de"))
|
||||||
|
|
||||||
echo x == "<a href=\"nimrod.de\">www.nimrod-test.de"
|
echo($x == "<a href=\"nimrod.de\">www.nimrod-test.de</a>")
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5,11 +5,11 @@ tambsym2.nim;4;undeclared identifier: 'CreateRGBSurface'
|
||||||
tambsym3.nim;6;ambiguous identifier
|
tambsym3.nim;6;ambiguous identifier
|
||||||
tatomic.nim;2;identifier expected, but found 'atomic'
|
tatomic.nim;2;identifier expected, but found 'atomic'
|
||||||
tbind2.nim;7;ambiguous call
|
tbind2.nim;7;ambiguous call
|
||||||
tbind4.nim;4;instantiation from here
|
tbind4.nim;4;undeclared identifier: 'lastId'
|
||||||
tblock1.nim;9;undeclared identifier: 'ha'
|
tblock1.nim;9;undeclared identifier: 'ha'
|
||||||
tconstr1.nim;20;type mismatch
|
tconstr1.nim;20;type mismatch
|
||||||
tillrec.nim;8;illegal recursion in type 'TIllegal'
|
tillrec.nim;8;illegal recursion in type 'TIllegal'
|
||||||
tinc.nim;3;to var type a variable needs to be passed
|
tinc.nim;3;for a 'var' type a variable needs to be passed
|
||||||
tinout.nim;7;for a 'var' type a variable needs to be passed
|
tinout.nim;7;for a 'var' type a variable needs to be passed
|
||||||
tinvalidnewseq.nim;10;type mismatch: got (array[0..6, string], int)
|
tinvalidnewseq.nim;10;type mismatch: got (array[0..6, string], int)
|
||||||
tinvwhen.nim;6;invalid indentation
|
tinvwhen.nim;6;invalid indentation
|
||||||
|
|
|
||||||
|
6
tests/reject/tambsym2.nim
Executable file
6
tests/reject/tambsym2.nim
Executable file
|
|
@ -0,0 +1,6 @@
|
||||||
|
|
||||||
|
from sdl import PSurface
|
||||||
|
|
||||||
|
discard SDL.CreateRGBSurface(SDL.SWSURFACE, 23, 34,
|
||||||
|
32, 0x00FF0000, 0x0000FF00, 0x000000FF, 0xff000000)
|
||||||
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
var x = 0
|
var x = 0
|
||||||
|
|
||||||
inc(x+1) #ERROR_MSG to var type a variable needs to be passed
|
inc(x+1)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,6 @@ type
|
||||||
msg: string,
|
msg: string,
|
||||||
err: bool]
|
err: bool]
|
||||||
TOutp = tuple[file, outp: string]
|
TOutp = tuple[file, outp: string]
|
||||||
TResult = tuple[test, expected, given: string, success: bool]
|
|
||||||
TResults = object
|
TResults = object
|
||||||
total, passed: int
|
total, passed: int
|
||||||
data: string
|
data: string
|
||||||
|
|
@ -100,7 +99,7 @@ proc colorBool(b: bool): string =
|
||||||
const
|
const
|
||||||
TableHeader4 = "<table border=\"1\"><tr><td>Test</td><td>Expected</td>" &
|
TableHeader4 = "<table border=\"1\"><tr><td>Test</td><td>Expected</td>" &
|
||||||
"<td>Given</td><td>Success</td></tr>\n"
|
"<td>Given</td><td>Success</td></tr>\n"
|
||||||
TableHeader3 = "<table border=\"1\"><tr><td>Test</td><td>Expected</td>" &
|
TableHeader3 = "<table border=\"1\"><tr><td>Test</td>" &
|
||||||
"<td>Given</td><td>Success</td></tr>\n"
|
"<td>Given</td><td>Success</td></tr>\n"
|
||||||
TableFooter = "</table>\n"
|
TableFooter = "</table>\n"
|
||||||
|
|
||||||
|
|
@ -150,8 +149,6 @@ proc reject(r: var TResults, dir, options: string) =
|
||||||
var given = callCompiler(test, options)
|
var given = callCompiler(test, options)
|
||||||
cmpMsgs(r, specs[expected], given, t)
|
cmpMsgs(r, specs[expected], given, t)
|
||||||
|
|
||||||
if r.total > 3: break
|
|
||||||
|
|
||||||
proc compile(r: var TResults, pattern, options: string) =
|
proc compile(r: var TResults, pattern, options: string) =
|
||||||
for test in os.walkFiles(pattern):
|
for test in os.walkFiles(pattern):
|
||||||
var t = extractFilename(test)
|
var t = extractFilename(test)
|
||||||
|
|
@ -159,7 +156,6 @@ proc compile(r: var TResults, pattern, options: string) =
|
||||||
var given = callCompiler(test, options)
|
var given = callCompiler(test, options)
|
||||||
r.addResult(t, given.msg, not given.err)
|
r.addResult(t, given.msg, not given.err)
|
||||||
if not given.err: inc(r.passed)
|
if not given.err: inc(r.passed)
|
||||||
if r.total > 3: break
|
|
||||||
|
|
||||||
proc run(r: var TResults, dir, options: string) =
|
proc run(r: var TResults, dir, options: string) =
|
||||||
var specs = parseRunData(dir)
|
var specs = parseRunData(dir)
|
||||||
|
|
@ -179,7 +175,6 @@ proc run(r: var TResults, dir, options: string) =
|
||||||
r.addResult(t, expected.outp, buf, success)
|
r.addResult(t, expected.outp, buf, success)
|
||||||
else:
|
else:
|
||||||
r.addResult(t, expected.outp, "executable not found", false)
|
r.addResult(t, expected.outp, "executable not found", false)
|
||||||
if r.total > 3: break
|
|
||||||
|
|
||||||
var options = ""
|
var options = ""
|
||||||
var rejectRes = initResults()
|
var rejectRes = initResults()
|
||||||
|
|
|
||||||
|
|
@ -65,7 +65,7 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div id="footer">
|
<div id="footer">
|
||||||
copyright © 2009 $c.authors | Last update: ${getDateStr()}
|
copyright © 2010 $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://validator.w3.org/check?uri=referer">XHTML 1.1</a>
|
||||||
| <a class="reference" href="http://jigsaw.w3.org/css-validator/check/referer">CSS</a>
|
| <a class="reference" href="http://jigsaw.w3.org/css-validator/check/referer">CSS</a>
|
||||||
| <a class="reference" href="http://www.dcarter.co.uk">design by dcarter</a>
|
| <a class="reference" href="http://www.dcarter.co.uk">design by dcarter</a>
|
||||||
|
|
|
||||||
|
|
@ -3,8 +3,8 @@
|
||||||
|
|
||||||
Here you can download the latest version of the Nimrod Compiler.
|
Here you can download the latest version of the Nimrod Compiler.
|
||||||
Please choose your platform:
|
Please choose your platform:
|
||||||
* source-based installation: `<download/nimrod_0.8.6.zip>`_
|
* source-based installation: `<download/nimrod_0.8.8.zip>`_
|
||||||
* installer for Windows XP/Vista (i386): `<download/nimrod_0.8.6.exe>`_
|
* installer for Windows XP/Vista (i386): `<download/nimrod_0.8.8.exe>`_
|
||||||
(includes GCC and everything else you need)
|
(includes GCC and everything else you need)
|
||||||
|
|
||||||
The source-based installation has been tested on these systems:
|
The source-based installation has been tested on these systems:
|
||||||
|
|
|
||||||
11
web/news.txt
11
web/news.txt
|
|
@ -2,7 +2,7 @@
|
||||||
News
|
News
|
||||||
====
|
====
|
||||||
|
|
||||||
2010-XX-XX Version 0.8.8 released
|
2010-03-14 Version 0.8.8 released
|
||||||
=================================
|
=================================
|
||||||
|
|
||||||
Version 0.8.8 has been released! Get it `here <download.html>`_.
|
Version 0.8.8 has been released! Get it `here <download.html>`_.
|
||||||
|
|
@ -22,9 +22,10 @@ Bugfixes
|
||||||
- An overloadable symbol can now have the same name as an imported module.
|
- An overloadable symbol can now have the same name as an imported module.
|
||||||
- Fixed a serious bug in ``strutils.cmpIgnoreCase``.
|
- Fixed a serious bug in ``strutils.cmpIgnoreCase``.
|
||||||
- Fixed ``unicode.toUTF8``.
|
- Fixed ``unicode.toUTF8``.
|
||||||
- The compiler now rejects ``'\n'``.
|
- The compiler now rejects ``'\n'`` (use ``"\n"`` instead).
|
||||||
- ``times.getStartMilsecs()`` now works on Mac OS X.
|
- ``times.getStartMilsecs()`` now works on Mac OS X.
|
||||||
- Fixed a bug in ``pegs.match`` concerning start offsets.
|
- Fixed a bug in ``pegs.match`` concerning start offsets.
|
||||||
|
- Lots of other little bugfixes.
|
||||||
|
|
||||||
|
|
||||||
Additions
|
Additions
|
||||||
|
|
@ -57,9 +58,8 @@ Additions
|
||||||
You can change your configuration file to use these.
|
You can change your configuration file to use these.
|
||||||
- Triple quoted strings allow for ``"`` in more contexts.
|
- Triple quoted strings allow for ``"`` in more contexts.
|
||||||
- ``""`` within raw string literals stands for a single quotation mark.
|
- ``""`` within raw string literals stands for a single quotation mark.
|
||||||
- More extensive subscript operator overloading. See
|
- Arguments to ``openArray`` parameters can be left out.
|
||||||
`subscript overloading <manual.html#subscript-overloading>`_ for further
|
- More extensive subscript operator overloading. (To be documented.)
|
||||||
information.
|
|
||||||
- The documentation generator supports the ``.. raw:: html`` directive.
|
- The documentation generator supports the ``.. raw:: html`` directive.
|
||||||
- The Pegs module supports back references via the notation ``$capture_index``.
|
- The Pegs module supports back references via the notation ``$capture_index``.
|
||||||
|
|
||||||
|
|
@ -82,6 +82,7 @@ Changes affecting backwards compatibility
|
||||||
- The ``\w`` character class for pegs now includes the digits ``'0'..'9'``.
|
- The ``\w`` character class for pegs now includes the digits ``'0'..'9'``.
|
||||||
- Many wrappers now do not contain redundant name prefixes (like ``GTK_``,
|
- Many wrappers now do not contain redundant name prefixes (like ``GTK_``,
|
||||||
``lua``) anymore.
|
``lua``) anymore.
|
||||||
|
- Arguments to ``openArray`` parameters can be left out.
|
||||||
|
|
||||||
|
|
||||||
2009-12-21 Version 0.8.6 released
|
2009-12-21 Version 0.8.6 released
|
||||||
|
|
|
||||||
|
|
@ -23,13 +23,15 @@ file: ticker
|
||||||
[Documentation]
|
[Documentation]
|
||||||
doc: "endb;intern;apis;lib;manual;tut1;tut2;nimrodc;overview"
|
doc: "endb;intern;apis;lib;manual;tut1;tut2;nimrodc;overview"
|
||||||
pdf: "manual;lib;tut1;tut2;nimrodc"
|
pdf: "manual;lib;tut1;tut2;nimrodc"
|
||||||
srcdoc: "system.nim;pure/os;pure/strutils;pure/regexprs;pure/math"
|
srcdoc: "impure/graphics;pure/sockets"
|
||||||
|
srcdoc: "system.nim;pure/os;pure/strutils;pure/re;pure/math"
|
||||||
srcdoc: "pure/complex;pure/times;pure/osproc;pure/pegs;pure/dynlib"
|
srcdoc: "pure/complex;pure/times;pure/osproc;pure/pegs;pure/dynlib"
|
||||||
srcdoc: "pure/parseopt;pure/hashes;pure/strtabs;pure/lexbase"
|
srcdoc: "pure/parseopt;pure/hashes;pure/strtabs;pure/lexbase"
|
||||||
srcdoc: "pure/parsecfg;pure/parsexml;pure/parsecsv;pure/parsesql"
|
srcdoc: "pure/parsecfg;pure/parsexml;pure/parsecsv;pure/parsesql"
|
||||||
srcdoc: "pure/streams;pure/terminal;pure/cgi;impure/web;pure/unicode"
|
srcdoc: "pure/streams;pure/terminal;pure/cgi;impure/web;pure/unicode"
|
||||||
srcdoc: "impure/zipfiles;pure/xmlgen;pure/macros;pure/parseutils;pure/browsers"
|
srcdoc: "impure/zipfiles;pure/xmlgen;pure/macros;pure/parseutils;pure/browsers"
|
||||||
srcdoc: "impure/db_postgres;impure/db_mysql;pure/httpserver;pure/httpclient"
|
srcdoc: "impure/db_postgres;impure/db_mysql;impure/db_sqlite"
|
||||||
|
srcdoc: "pure/httpserver;pure/httpclient"
|
||||||
srcdoc: "pure/ropes;pure/unidecode/unidecode;pure/xmldom;pure/xmldomparser"
|
srcdoc: "pure/ropes;pure/unidecode/unidecode;pure/xmldom;pure/xmldomparser"
|
||||||
srcdoc: "pure/xmlparser;pure/htmlparser;pure/xmltree;pure/colors;impure/graphics"
|
srcdoc: "pure/xmlparser;pure/htmlparser;pure/xmltree;pure/colors;impure/graphics"
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -28,7 +28,7 @@ flexibility for speed. You get both.
|
||||||
Why is it named Nimrod?
|
Why is it named Nimrod?
|
||||||
-----------------------
|
-----------------------
|
||||||
You have to find out for yourself. If you don't find a tongue-in-cheek
|
You have to find out for yourself. If you don't find a tongue-in-cheek
|
||||||
interpretation you have to look harder.
|
interpretation you will have to look harder.
|
||||||
|
|
||||||
|
|
||||||
How is Nimrod licensed?
|
How is Nimrod licensed?
|
||||||
|
|
@ -44,15 +44,17 @@ How stable is Nimrod?
|
||||||
|
|
||||||
The compiler is in development and some important features are still missing.
|
The compiler is in development and some important features are still missing.
|
||||||
However, the compiler is quite stable already: It is able to compile itself
|
However, the compiler is quite stable already: It is able to compile itself
|
||||||
and a substantial body of other code. Until version 1.0.0 is released, slight
|
and a substantial body of other code. Until version 1.0.0 is released,
|
||||||
incompabilities with older versions of the compiler may be introduced.
|
incompabilities with older versions of the compiler will be introduced. The
|
||||||
|
semantic details of overloading, macros/templates/generics and iterators
|
||||||
|
and their interactions are subject to change.
|
||||||
|
|
||||||
|
|
||||||
How fast is Nimrod?
|
How fast is Nimrod?
|
||||||
-------------------
|
-------------------
|
||||||
Benchmarks have not been ported yet and support for threads is missing. But in
|
Benchmarks have not been ported yet and support for threads is missing. But in
|
||||||
the worst case, you can get exactly the same performance as C if you decide to
|
the worst case, you can get exactly the same performance as in C if you decide
|
||||||
write as low-level Nimrod code as C requires you to do. That said the only
|
to write as low-level Nimrod code as C requires you to do. That said the only
|
||||||
overhead Nimrod has over C is the GC which has been tuned for years (and is
|
overhead Nimrod has over C is the GC which has been tuned for years (and is
|
||||||
significantly faster than the Boehm GC).
|
significantly faster than the Boehm GC).
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,9 @@
|
||||||
|
| `2010-03-14`:newsdate:
|
||||||
|
| Nimrod version 0.8.8 has been released!
|
||||||
|
Get it `here <./download.html>`_.
|
||||||
|
|
||||||
| `2009-12-21`:newsdate:
|
| `2009-12-21`:newsdate:
|
||||||
| Nimrod version 0.8.6 has been released!
|
| Nimrod version 0.8.6 has been released!
|
||||||
Get it `here <./download.html>`_.
|
|
||||||
|
|
||||||
| `2009-10-21`:newsdate:
|
| `2009-10-21`:newsdate:
|
||||||
| Nimrod version 0.8.2 has been released!
|
| Nimrod version 0.8.2 has been released!
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue