version 0.7.4

This commit is contained in:
Andreas Rumpf 2009-01-07 17:03:25 +01:00
commit 439aa2d04d
114 changed files with 13664 additions and 10110 deletions

View file

@ -102,51 +102,16 @@ proc absInt(a: int): int {.compilerProc, inline.} =
raiseOverflow()
const
asmVersion = defined(I386) and (defined(vcc) or defined(wcc) or defined(dmc))
asmVersion = defined(I386) and (defined(vcc) or defined(wcc) or
defined(dmc) or defined(gcc) or defined(llvm_gcc))
# my Version of Borland C++Builder does not have
# tasm32, which is needed for assembler blocks
# this is why Borland is not included in the 'when'
useInline = not asmVersion
when asmVersion and defined(gcc):
proc addInt(a, b: int): int {.compilerProc, pure, inline.}
proc subInt(a, b: int): int {.compilerProc, pure, inline.}
proc mulInt(a, b: int): int {.compilerProc, pure, inline.}
proc divInt(a, b: int): int {.compilerProc, pure, inline.}
proc modInt(a, b: int): int {.compilerProc, pure, inline.}
proc negInt(a: int): int {.compilerProc, pure, inline.}
elif asmVersion:
proc addInt(a, b: int): int {.compilerProc, pure.}
proc subInt(a, b: int): int {.compilerProc, pure.}
proc mulInt(a, b: int): int {.compilerProc, pure.}
proc divInt(a, b: int): int {.compilerProc, pure.}
proc modInt(a, b: int): int {.compilerProc, pure.}
proc negInt(a: int): int {.compilerProc, pure.}
elif useInline:
proc addInt(a, b: int): int {.compilerProc, inline.}
proc subInt(a, b: int): int {.compilerProc, inline.}
proc mulInt(a, b: int): int {.compilerProc.}
# mulInt is to large for inlining?
proc divInt(a, b: int): int {.compilerProc, inline.}
proc modInt(a, b: int): int {.compilerProc, inline.}
proc negInt(a: int): int {.compilerProc, inline.}
else:
proc addInt(a, b: int): int {.compilerProc.}
proc subInt(a, b: int): int {.compilerProc.}
proc mulInt(a, b: int): int {.compilerProc.}
proc divInt(a, b: int): int {.compilerProc.}
proc modInt(a, b: int): int {.compilerProc.}
proc negInt(a: int): int {.compilerProc.}
# implementation:
when asmVersion and not defined(gcc):
when asmVersion and not defined(gcc) and not defined(llvm_gcc):
# assembler optimized versions for compilers that
# have an intel syntax assembler:
proc addInt(a, b: int): int =
proc addInt(a, b: int): int {.compilerProc, pure.} =
# a in eax, and b in edx
asm """
mov eax, `a`
@ -156,7 +121,7 @@ when asmVersion and not defined(gcc):
theEnd:
"""
proc subInt(a, b: int): int =
proc subInt(a, b: int): int {.compilerProc, pure.} =
asm """
mov eax, `a`
sub eax, `b`
@ -165,7 +130,7 @@ when asmVersion and not defined(gcc):
theEnd:
"""
proc negInt(a: int): int =
proc negInt(a: int): int {.compilerProc, pure.} =
asm """
mov eax, `a`
neg eax
@ -174,7 +139,7 @@ when asmVersion and not defined(gcc):
theEnd:
"""
proc divInt(a, b: int): int =
proc divInt(a, b: int): int {.compilerProc, pure.} =
asm """
mov eax, `a`
mov ecx, `b`
@ -185,7 +150,7 @@ when asmVersion and not defined(gcc):
theEnd:
"""
proc modInt(a, b: int): int =
proc modInt(a, b: int): int {.compilerProc, pure.} =
asm """
mov eax, `a`
mov ecx, `b`
@ -197,7 +162,7 @@ when asmVersion and not defined(gcc):
mov eax, edx
"""
proc mulInt(a, b: int): int =
proc mulInt(a, b: int): int {.compilerProc, pure.} =
asm """
mov eax, `a`
mov ecx, `b`
@ -208,99 +173,105 @@ when asmVersion and not defined(gcc):
theEnd:
"""
elif asmVersion and defined(gcc):
proc addInt(a, b: int): int =
asm """ "addl %1,%%eax\n"
elif false: # asmVersion and (defined(gcc) or defined(llvm_gcc)):
proc addInt(a, b: int): int {.compilerProc, inline.} =
# don't use a pure proc here!
asm """
"addl %%ecx, %%eax\n"
"jno 1\n"
"call _raiseOverflow\n"
"1: \n"
:"=a"(`result`)
:"a"(`a`), "c"(`b`)
"""
proc subInt(a, b: int): int {.compilerProc, inline.} =
asm """ "subl %%ecx,%%eax\n"
"jno 1\n"
"call _raiseOverflow\n"
"1: \n"
:"=a"(`result`)
:"a"(`a`), "c"(`b`)
"""
proc mulInt(a, b: int): int {.compilerProc, inline.} =
asm """ "xorl %%edx, %%edx\n"
"imull %%ecx\n"
"jno 1\n"
"call _raiseOverflow\n"
"1: \n"
:"=a"(`a`)
:"a"(`a`), "r"(`b`)
:"=a"(`result`)
:"a"(`a`), "c"(`b`)
:"%edx"
"""
proc subInt(a, b: int): int =
asm """ "subl %1,%%eax\n"
"jno 1\n"
"call _raiseOverflow\n"
"1: \n"
:"=a"(`a`)
:"a"(`a`), "r"(`b`)
proc negInt(a: int): int {.compilerProc, inline.} =
asm """ "negl %%eax\n"
"jno 1\n"
"call _raiseOverflow\n"
"1: \n"
:"=a"(`result`)
:"a"(`a`)
"""
proc negInt(a: int): int =
asm """ "negl %%eax\n"
"jno 1\n"
"call _raiseOverflow\n"
"1: \n"
:"=a"(`a`)
:"a"(`a`)
"""
proc divInt(a, b: int): int =
proc divInt(a, b: int): int {.compilerProc, inline.} =
asm """ "xorl %%edx, %%edx\n"
"idivl %%ecx\n"
"jno 1\n"
"call _raiseOverflow\n"
"1: \n"
:"=a"(`a`)
:"a"(`a`), "c"(`b`)
:"%edx"
:"=a"(`result`)
:"a"(`a`), "c"(`b`)
:"%edx"
"""
proc modInt(a, b: int): int =
proc modInt(a, b: int): int {.compilerProc, inline.} =
asm """ "xorl %%edx, %%edx\n"
"idivl %%ecx\n"
"jno 1\n"
"call _raiseOverflow\n"
"1: \n"
"movl %%edx, %%eax"
:"=a"(`a`)
:"a"(`a`), "c"(`b`)
:"%edx"
:"=a"(`result`)
:"a"(`a`), "c"(`b`)
:"%edx"
"""
proc mulInt(a, b: int): int =
asm """ "xorl %%edx, %%edx\n"
"imull %%ecx\n"
"jno 1\n"
"call _raiseOverflow\n"
"1: \n"
:"=a"(`a`)
:"a"(`a`), "c"(`b`)
:"%edx"
"""
else:
# Platform independant versions of the above (slower!)
proc addInt(a, b: int): int =
# Platform independant versions of the above (slower!)
when not defined(addInt):
proc addInt(a, b: int): int {.compilerProc, inline.} =
result = a +% b
if (result xor a) >= 0 or (result xor b) >= 0:
return result
raiseOverflow()
proc subInt(a, b: int): int =
when not defined(subInt):
proc subInt(a, b: int): int {.compilerProc, inline.} =
result = a -% b
if (result xor a) >= 0 or (result xor not b) >= 0:
return result
raiseOverflow()
proc negInt(a: int): int =
when not defined(negInt):
proc negInt(a: int): int {.compilerProc, inline.} =
if a != low(int): return -a
raiseOverflow()
proc divInt(a, b: int): int =
when not defined(divInt):
proc divInt(a, b: int): int {.compilerProc, inline.} =
if b == 0:
raiseDivByZero()
if a == low(int) and b == -1:
raiseOverflow()
return a div b
proc modInt(a, b: int): int =
when not defined(modInt):
proc modInt(a, b: int): int {.compilerProc, inline.} =
if b == 0:
raiseDivByZero()
return a mod b
when not defined(mulInt):
#
# This code has been inspired by Python's source code.
# The native int product x*y is either exactly right or *way* off, being
@ -321,7 +292,7 @@ else:
# the only one that can lose catastrophic amounts of information, it's the
# native int product that must have overflowed.
#
proc mulInt(a, b: int): int =
proc mulInt(a, b: int): int {.compilerProc.} =
var
resAsFloat, floatProd: float

View file

@ -281,7 +281,7 @@ proc getServerSoftware*(): string =
proc setTestData*(keysvalues: openarray[string]) =
## fills the appropriate environment variables to test your CGI application.
## This can only simulate the 'GET' 'REQUEST_METHOD'. `keysvalues` should
## This can only simulate the 'GET' request method. `keysvalues` should
## provide embedded (name, value)-pairs. Example:
##
## .. code-block:: Nimrod
@ -300,6 +300,7 @@ proc setTestData*(keysvalues: openarray[string]) =
proc writeContentType*() =
## call this before starting to send your HTML data to `stdout`. This
## is just a shorthand for:
##
## .. code-block:: Nimrod
## write(stdout, "Content-type: text/html\n\n")
write(stdout, "Content-type: text/html\n\n")

View file

@ -1,3 +1,5 @@
{.deadCodeElim: on.}
import
glib2

View file

@ -1,3 +1,5 @@
{.deadCodeElim: on.}
import
glib2, gdk2pixbuf, pango

View file

@ -1,3 +1,5 @@
{.deadCodeElim: on.}
import
glib2

View file

@ -1,3 +1,5 @@
{.deadCodeElim: on.}
import
Glib2, Gdk2

View file

@ -1,3 +1,5 @@
{.deadCodeElim: on.}
when defined(windows):
const
gliblib = "libglib-2.0-0.dll"

View file

@ -1,3 +1,5 @@
{.deadCodeElim: on.}
import
glib2, atk, pango, gdk2pixbuf, gdk2

View file

@ -1,3 +1,5 @@
{.deadCodeElim: on.}
import
Glib2, Gdk2, Gtk2, GdkGLExt

View file

@ -1,3 +1,5 @@
{.deadCodeElim: on.}
import
gtk2, glib2, atk, pango, gdk2pixbuf, gdk2

View file

@ -1,3 +1,5 @@
{.deadCodeElim: on.}
import
glib2, gtk2

View file

@ -1,3 +1,5 @@
{.deadCodeElim: on.}
import
glib2

View file

@ -1,3 +1,5 @@
{.deadCodeElim: on.}
import
glib2, pango

View file

@ -270,7 +270,8 @@
#
#
#
{.deadCodeElim: on.}
when defined(windows):
const SDLLibName = "SDL.dll"
elif defined(macosx):

View file

@ -2,93 +2,93 @@
#******************************************************************************
#
# $Id: sdl_mixer.pas,v 1.18 2007/05/29 21:31:44 savage Exp $
#
#
#
# Borland Delphi SDL_Mixer - Simple DirectMedia Layer Mixer Library
# Conversion of the Simple DirectMedia Layer Headers
#
# Portions created by Sam Lantinga <slouken@devolution.com> are
# Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga
# 5635-34 Springhouse Dr.
# Pleasanton, CA 94588 (USA)
#
# All Rights Reserved.
#
# The original files are : SDL_mixer.h
# music_cmd.h
# wavestream.h
# timidity.h
# playmidi.h
# music_ogg.h
# mikmod.h
#
# The initial developer of this Pascal code was :
# Dominqiue Louis <Dominique@SavageSoftware.com.au>
#
# Portions created by Dominqiue Louis are
# Copyright (C) 2000 - 2001 Dominqiue Louis.
#
#
# Contributor(s)
# --------------
# Matthias Thoma <ma.thoma@gmx.de>
#
# Obtained through:
# Joint Endeavour of Delphi Innovators ( Project JEDI )
#
# You may retrieve the latest version of this file at the Project
# JEDI home page, located at http://delphi-jedi.org
#
# The contents of this file are used with permission, subject to
# the Mozilla Public License Version 1.1 (the "License"); you may
# not use this file except in compliance with the License. You may
# obtain a copy of the License at
# http://www.mozilla.org/MPL/MPL-1.1.html
#
# Software distributed under the License is distributed on an
# "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
# implied. See the License for the specific language governing
# rights and limitations under the License.
#
# Description
# -----------
#
#
#
#
#
#
#
# Requires
# --------
# SDL.pas & SMPEG.pas somewhere within your search path.
#
# Programming Notes
# -----------------
# See the Aliens Demo to see how this library is used
#
# Revision History
# ----------------
# April 02 2001 - DL : Initial Translation
#
# February 02 2002 - DL : Update to version 1.2.1
#
# April 03 2003 - DL : Added jedi-sdl.inc include file to support more
# Pascal compilers. Initial support is now included
# for GnuPascal, VirtualPascal, TMT and obviously
# continue support for Delphi Kylix and FreePascal.
#
#
#
# Borland Delphi SDL_Mixer - Simple DirectMedia Layer Mixer Library
# Conversion of the Simple DirectMedia Layer Headers
#
# Portions created by Sam Lantinga <slouken@devolution.com> are
# Copyright (C) 1997, 1998, 1999, 2000, 2001 Sam Lantinga
# 5635-34 Springhouse Dr.
# Pleasanton, CA 94588 (USA)
#
# All Rights Reserved.
#
# The original files are : SDL_mixer.h
# music_cmd.h
# wavestream.h
# timidity.h
# playmidi.h
# music_ogg.h
# mikmod.h
#
# The initial developer of this Pascal code was :
# Dominqiue Louis <Dominique@SavageSoftware.com.au>
#
# Portions created by Dominqiue Louis are
# Copyright (C) 2000 - 2001 Dominqiue Louis.
#
#
# Contributor(s)
# --------------
# Matthias Thoma <ma.thoma@gmx.de>
#
# Obtained through:
# Joint Endeavour of Delphi Innovators ( Project JEDI )
#
# You may retrieve the latest version of this file at the Project
# JEDI home page, located at http://delphi-jedi.org
#
# The contents of this file are used with permission, subject to
# the Mozilla Public License Version 1.1 (the "License"); you may
# not use this file except in compliance with the License. You may
# obtain a copy of the License at
# http://www.mozilla.org/MPL/MPL-1.1.html
#
# Software distributed under the License is distributed on an
# "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
# implied. See the License for the specific language governing
# rights and limitations under the License.
#
# Description
# -----------
#
#
#
#
#
#
#
# Requires
# --------
# SDL.pas & SMPEG.pas somewhere within your search path.
#
# Programming Notes
# -----------------
# See the Aliens Demo to see how this library is used
#
# Revision History
# ----------------
# April 02 2001 - DL : Initial Translation
#
# February 02 2002 - DL : Update to version 1.2.1
#
# April 03 2003 - DL : Added jedi-sdl.inc include file to support more
# Pascal compilers. Initial support is now included
# for GnuPascal, VirtualPascal, TMT and obviously
# continue support for Delphi Kylix and FreePascal.
#
# April 24 2003 - DL : under instruction from Alexey Barkovoy, I have added
# better TMT Pascal support and under instruction
# better TMT Pascal support and under instruction
# from Prof. Abimbola Olowofoyeku (The African Chief),
# I have added better Gnu Pascal support
#
# April 30 2003 - DL : under instruction from David Mears AKA
# Jason Siletto, I have added FPC Linux support.
# This was compiled with fpc 1.1, so remember to set
# include file path. ie. -Fi/usr/share/fpcsrc/rtl/*
#
# I have added better Gnu Pascal support
#
# April 30 2003 - DL : under instruction from David Mears AKA
# Jason Siletto, I have added FPC Linux support.
# This was compiled with fpc 1.1, so remember to set
# include file path. ie. -Fi/usr/share/fpcsrc/rtl/*
#
#
# $Log: sdl_mixer.pas,v $
# Revision 1.18 2007/05/29 21:31:44 savage
@ -166,19 +166,19 @@ const
MIX_MAJOR_VERSION* = SDL_MIXER_MAJOR_VERSION
MIX_MINOR_VERSION* = SDL_MIXER_MINOR_VERSION
MIX_PATCHLEVEL* = SDL_MIXER_PATCHLEVEL # SDL_Mixer.h constants
# The default mixer has 8 simultaneous mixing channels
MIX_CHANNELS* = 8 # Good default values for a PC soundcard
# The default mixer has 8 simultaneous mixing channels
MIX_CHANNELS* = 8 # Good default values for a PC soundcard
MIX_DEFAULT_FREQUENCY* = 22050
when defined(IA32):
const
when defined(IA32):
const
MIX_DEFAULT_FORMAT* = AUDIO_S16LSB
else:
const
else:
const
MIX_DEFAULT_FORMAT* = AUDIO_S16MSB
const
const
MIX_DEFAULT_CHANNELS* = 2
MIX_MAX_VOLUME* = 128 # Volume of a chunk
MIX_MAX_VOLUME* = 128 # Volume of a chunk
PATH_MAX* = 255 # mikmod.h constants
#*
# * Library version
@ -204,7 +204,7 @@ type #music_cmd.h types
cvt*: TSDL_AudioCVT
PMidiEvent* = ptr TMidiEvent
TMidiEvent*{.final.} = object
TMidiEvent*{.final.} = object
time*: int32
channel*: uint8
type_*: uint8
@ -228,43 +228,43 @@ type #music_cmd.h types
len_available*: int
snd_available*: PUint8
TErrorEnum* = enum
MMERR_OPENING_FILE, MMERR_OUT_OF_MEMORY, MMERR_DYNAMIC_LINKING,
MMERR_SAMPLE_TOO_BIG, MMERR_OUT_OF_HANDLES, MMERR_UNKNOWN_WAVE_TYPE,
MMERR_LOADING_PATTERN, MMERR_LOADING_TRACK, MMERR_LOADING_HEADER,
MMERR_LOADING_SAMPLEINFO, MMERR_NOT_A_MODULE, MMERR_NOT_A_STREAM,
MMERR_MED_SYNTHSAMPLES, MMERR_ITPACK_INVALID_DATA, MMERR_DETECTING_DEVICE,
MMERR_INVALID_DEVICE, MMERR_INITIALIZING_MIXER, MMERR_OPENING_AUDIO,
MMERR_8BIT_ONLY, MMERR_16BIT_ONLY, MMERR_STEREO_ONLY, MMERR_ULAW,
MMERR_NON_BLOCK, MMERR_AF_AUDIO_PORT, MMERR_AIX_CONFIG_INIT,
MMERR_AIX_CONFIG_CONTROL, MMERR_AIX_CONFIG_START, MMERR_GUS_SETTINGS,
MMERR_GUS_RESET, MMERR_GUS_TIMER, MMERR_HP_SETSAMPLESIZE, MMERR_HP_SETSPEED,
MMERR_HP_CHANNELS, MMERR_HP_AUDIO_OUTPUT, MMERR_HP_AUDIO_DESC,
MMERR_HP_BUFFERSIZE, MMERR_OSS_SETFRAGMENT, MMERR_OSS_SETSAMPLESIZE,
MMERR_OSS_SETSTEREO, MMERR_OSS_SETSPEED, MMERR_SGI_SPEED, MMERR_SGI_16BIT,
MMERR_SGI_8BIT, MMERR_SGI_STEREO, MMERR_SGI_MONO, MMERR_SUN_INIT,
MMERR_OS2_MIXSETUP, MMERR_OS2_SEMAPHORE, MMERR_OS2_TIMER, MMERR_OS2_THREAD,
MMERR_DS_PRIORITY, MMERR_DS_BUFFER, MMERR_DS_FORMAT, MMERR_DS_NOTIFY,
MMERR_DS_EVENT, MMERR_DS_THREAD, MMERR_DS_UPDATE, MMERR_WINMM_HANDLE,
MMERR_WINMM_ALLOCATED, MMERR_WINMM_DEVICEID, MMERR_WINMM_FORMAT,
TErrorEnum* = enum
MMERR_OPENING_FILE, MMERR_OUT_OF_MEMORY, MMERR_DYNAMIC_LINKING,
MMERR_SAMPLE_TOO_BIG, MMERR_OUT_OF_HANDLES, MMERR_UNKNOWN_WAVE_TYPE,
MMERR_LOADING_PATTERN, MMERR_LOADING_TRACK, MMERR_LOADING_HEADER,
MMERR_LOADING_SAMPLEINFO, MMERR_NOT_A_MODULE, MMERR_NOT_A_STREAM,
MMERR_MED_SYNTHSAMPLES, MMERR_ITPACK_INVALID_DATA, MMERR_DETECTING_DEVICE,
MMERR_INVALID_DEVICE, MMERR_INITIALIZING_MIXER, MMERR_OPENING_AUDIO,
MMERR_8BIT_ONLY, MMERR_16BIT_ONLY, MMERR_STEREO_ONLY, MMERR_ULAW,
MMERR_NON_BLOCK, MMERR_AF_AUDIO_PORT, MMERR_AIX_CONFIG_INIT,
MMERR_AIX_CONFIG_CONTROL, MMERR_AIX_CONFIG_START, MMERR_GUS_SETTINGS,
MMERR_GUS_RESET, MMERR_GUS_TIMER, MMERR_HP_SETSAMPLESIZE, MMERR_HP_SETSPEED,
MMERR_HP_CHANNELS, MMERR_HP_AUDIO_OUTPUT, MMERR_HP_AUDIO_DESC,
MMERR_HP_BUFFERSIZE, MMERR_OSS_SETFRAGMENT, MMERR_OSS_SETSAMPLESIZE,
MMERR_OSS_SETSTEREO, MMERR_OSS_SETSPEED, MMERR_SGI_SPEED, MMERR_SGI_16BIT,
MMERR_SGI_8BIT, MMERR_SGI_STEREO, MMERR_SGI_MONO, MMERR_SUN_INIT,
MMERR_OS2_MIXSETUP, MMERR_OS2_SEMAPHORE, MMERR_OS2_TIMER, MMERR_OS2_THREAD,
MMERR_DS_PRIORITY, MMERR_DS_BUFFER, MMERR_DS_FORMAT, MMERR_DS_NOTIFY,
MMERR_DS_EVENT, MMERR_DS_THREAD, MMERR_DS_UPDATE, MMERR_WINMM_HANDLE,
MMERR_WINMM_ALLOCATED, MMERR_WINMM_DEVICEID, MMERR_WINMM_FORMAT,
MMERR_WINMM_UNKNOWN, MMERR_MAC_SPEED, MMERR_MAC_START, MMERR_MAX
PMODULE* = ptr TMODULE
TMODULE*{.final.} = object
TMODULE*{.final.} = object
PUNIMOD* = ptr TUNIMOD
TUNIMOD* = TMODULE #SDL_mixer.h types
# The internal format for an audio chunk
# The internal format for an audio chunk
PMix_Chunk* = ptr TMix_Chunk
TMix_Chunk*{.final.} = object
TMix_Chunk*{.final.} = object
allocated*: int
abuf*: PUint8
alen*: Uint32
volume*: Uint8 # Per-sample volume, 0-128
Mix_Chunk* = TMix_Chunk # The different fading types supported
TMix_Fading* = enum
volume*: Uint8 # Per-sample volume, 0-128
Mix_Chunk* = TMix_Chunk # The different fading types supported
TMix_Fading* = enum
MIX_NO_FADING, MIX_FADING_OUT, MIX_FADING_IN
Mix_Fading* = TMix_Fading
TMix_MusicType* = enum
TMix_MusicType* = enum
MUS_NONE, MUS_CMD, MUS_WAV, MUS_MOD, MUS_MID, MUS_OGG, MUS_MP3
Mix_MusicType* = TMix_MusicType #
# TMusicUnion = record
@ -279,89 +279,84 @@ type #music_cmd.h types
# {$ENDIF}
# end;
PMix_Music* = ptr TMix_Music
TMix_Music*{.final.} = object # The internal format for a music chunk interpreted via mikmod
TMix_Music*{.final.} = object # The internal format for a music chunk interpreted via mikmod
type_*: TMix_MusicType # other fields are not aviable
# data : TMusicUnion;
# fading : TMix_Fading;
# fade_volume : integer;
# fade_step : integer;
# fade_steps : integer;
# error : integer;
# error : integer;
TMixFunction* = proc (udata: Pointer, stream: PUint8, length: int): Pointer{.
cdecl.} # This macro can be used to fill a version structure with the compile-time
# version of the SDL_mixer library.
# version of the SDL_mixer library.
proc SDL_MIXER_VERSION*(X: var TSDL_Version)
# This function gets the version of the dynamically linked SDL_mixer library.
# It should NOT be used to fill a version structure, instead you should use the
# SDL_MIXER_VERSION() macro.
# SDL_MIXER_VERSION() macro.
proc Mix_Linked_Version*(): PSDL_version{.cdecl, importc, dynlib: SDL_MixerLibName.}
# Open the mixer with a certain audio format
proc Mix_OpenAudio*(frequency: int, format: Uint16, channels: int,
# Open the mixer with a certain audio format
proc Mix_OpenAudio*(frequency: int, format: Uint16, channels: int,
chunksize: int): int{.cdecl, importc, dynlib: SDL_MixerLibName.}
# Dynamically change the number of channels managed by the mixer.
# If decreasing the number of channels, the upper channels are
# stopped.
# This function returns the new number of allocated channels.
#
proc Mix_AllocateChannels*(numchannels: int): int{.cdecl,
#
proc Mix_AllocateChannels*(numchannels: int): int{.cdecl,
importc, dynlib: SDL_MixerLibName.}
# Find out what the actual audio device parameters are.
# This function returns 1 if the audio has been opened, 0 otherwise.
#
#
proc Mix_QuerySpec*(frequency: var int, format: var Uint16, channels: var int): int{.
cdecl, importc, dynlib: SDL_MixerLibName.}
# Load a wave file or a music (.mod .s3m .it .xm) file
proc Mix_LoadWAV_RW*(src: PSDL_RWops, freesrc: int): PMix_Chunk{.cdecl,
# Load a wave file or a music (.mod .s3m .it .xm) file
proc Mix_LoadWAV_RW*(src: PSDL_RWops, freesrc: int): PMix_Chunk{.cdecl,
importc, dynlib: SDL_MixerLibName.}
proc Mix_LoadWAV*(filename: cstring): PMix_Chunk
proc Mix_LoadMUS*(filename: cstring): PMix_Music{.cdecl,
proc Mix_LoadMUS*(filename: cstring): PMix_Music{.cdecl,
importc, dynlib: SDL_MixerLibName.}
##if 0 { This hasn't been hooked into music.c yet }
#{ Load a music file from an SDL_RWop object (MikMod-specific currently)
# Matt Campbell (matt@campbellhome.dhs.org) April 2000 }
#function Mix_LoadMUS_RW(SDL_RWops *rw) : PMix_Music; cdecl;
##endif
# Load a wave file of the mixer format from a memory buffer
proc Mix_QuickLoad_WAV*(mem: PUint8): PMix_Chunk{.cdecl,
# Load a wave file of the mixer format from a memory buffer
proc Mix_QuickLoad_WAV*(mem: PUint8): PMix_Chunk{.cdecl,
importc, dynlib: SDL_MixerLibName.}
# Free an audio chunk previously loaded
# Free an audio chunk previously loaded
proc Mix_FreeChunk*(chunk: PMix_Chunk){.cdecl, importc, dynlib: SDL_MixerLibName.}
proc Mix_FreeMusic*(music: PMix_Music){.cdecl, importc, dynlib: SDL_MixerLibName.}
# Find out the music format of a mixer music, or the currently playing
# music, if 'music' is NULL.
proc Mix_GetMusicType*(music: PMix_Music): TMix_MusicType{.cdecl,
proc Mix_GetMusicType*(music: PMix_Music): TMix_MusicType{.cdecl,
importc, dynlib: SDL_MixerLibName.}
# Set a function that is called after all mixing is performed.
# This can be used to provide real-time visual display of the audio stream
# or add a custom mixer filter for the stream data.
#
proc Mix_SetPostMix*(mix_func: TMixFunction, arg: Pointer){.cdecl,
proc Mix_SetPostMix*(mix_func: TMixFunction, arg: Pointer){.cdecl,
importc, dynlib: SDL_MixerLibName.}
# Add your own music player or additional mixer function.
# If 'mix_func' is NULL, the default music player is re-enabled.
#
proc Mix_HookMusic*(mix_func: TMixFunction, arg: Pointer){.cdecl,
#
proc Mix_HookMusic*(mix_func: TMixFunction, arg: Pointer){.cdecl,
importc, dynlib: SDL_MixerLibName.}
# Add your own callback when the music has finished playing.
#
proc Mix_HookMusicFinished*(music_finished: Pointer){.cdecl,
#
proc Mix_HookMusicFinished*(music_finished: Pointer){.cdecl,
importc, dynlib: SDL_MixerLibName.}
# Get a pointer to the user data for the current music hook
# Get a pointer to the user data for the current music hook
proc Mix_GetMusicHookData*(): Pointer{.cdecl, importc, dynlib: SDL_MixerLibName.}
#* Add your own callback when a channel has finished playing. NULL
# * to disable callback.*
type
type
TChannel_finished* = proc (channel: int){.cdecl.}
proc Mix_ChannelFinished*(channel_finished: TChannel_finished){.cdecl,
proc Mix_ChannelFinished*(channel_finished: TChannel_finished){.cdecl,
importc, dynlib: SDL_MixerLibName.}
const
const
MIX_CHANNEL_POST* = - 2
# This is the format of a special effect callback:
# myeffect(int chan, void *stream, int len, void *udata);
#
#
# (chan) is the channel number that your effect is affecting. (stream) is
# the buffer of data to work upon. (len) is the size of (stream), and
# (udata) is a user-defined bit of data, which you pass as the last arg of
@ -372,10 +367,10 @@ const
# down the mixing pipeline, through any other effect functions, then finally
# to be mixed with the rest of the channels and music for the final output
# stream.
#
#
type
TMix_EffectFunc* = proc (chan: int, stream: Pointer, length: int,
type
TMix_EffectFunc* = proc (chan: int, stream: Pointer, length: int,
udata: Pointer): Pointer{.cdecl.}
# * This is a callback that signifies that a channel has finished all its
# * loops and has completed playback. This gets called if the buffer
@ -428,7 +423,7 @@ type
# * Error messages can be retrieved from Mix_GetError().
# *
proc Mix_RegisterEffect*(chan: int, f: TMix_EffectFunc, d: TMix_EffectDone,
proc Mix_RegisterEffect*(chan: int, f: TMix_EffectFunc, d: TMix_EffectDone,
arg: Pointer): int{.cdecl, importc, dynlib: SDL_MixerLibName.}
#* You may not need to call this explicitly, unless you need to stop an
# * effect from processing in the middle of a chunk's playback.
@ -438,7 +433,7 @@ proc Mix_RegisterEffect*(chan: int, f: TMix_EffectFunc, d: TMix_EffectDone,
# * returns zero if error (no such channel or effect), nonzero if removed.
# * Error messages can be retrieved from Mix_GetError().
# *
proc Mix_UnregisterEffect*(channel: int, f: TMix_EffectFunc): int{.cdecl,
proc Mix_UnregisterEffect*(channel: int, f: TMix_EffectFunc): int{.cdecl,
importc, dynlib: SDL_MixerLibName.}
#* You may not need to call this explicitly, unless you need to stop all
# * effects from processing in the middle of a chunk's playback. Note that
@ -451,17 +446,17 @@ proc Mix_UnregisterEffect*(channel: int, f: TMix_EffectFunc): int{.cdecl,
# * returns zero if error( no such channel ), nonzero if all effects removed.
# * Error messages can be retrieved from Mix_GetError( ).
# *
proc Mix_UnregisterAllEffects*(channel: int): int{.cdecl,
proc Mix_UnregisterAllEffects*(channel: int): int{.cdecl,
importc, dynlib: SDL_MixerLibName.}
const
MIX_EFFECTSMAXSPEED* = "MIX_EFFECTSMAXSPEED"
const
MIX_EFFECTSMAXSPEED* = "MIX_EFFECTSMAXSPEED"
# * These are the internally - defined mixing effects.They use the same API that
# * effects defined in the application use, but are provided here as a
# * convenience.Some effects can reduce their quality or use more memory in
# * the name of speed; to enable this, make sure the environment variable
# * MIX_EFFECTSMAXSPEED( see above ) is defined before you call
# * Mix_OpenAudio( ).
# *
# *
#* set the panning of a channel.The left and right channels are specified
# * as integers between 0 and 255, quietest to loudest, respectively.
# *
@ -486,9 +481,9 @@ const
# * nonzero if panning effect enabled.Note that an audio device in mono
# * mode is a no - op, but this call will return successful in that case .
# * Error messages can be retrieved from Mix_GetError( ).
# *
# *
proc Mix_SetPanning*(channel: int, left: Uint8, right: Uint8): int{.cdecl,
proc Mix_SetPanning*(channel: int, left: Uint8, right: Uint8): int{.cdecl,
importc, dynlib: SDL_MixerLibName.}
# * set the position ofa channel.( angle ) is an integer from 0 to 360, that
# * specifies the location of the sound in relation to the listener.( angle )
@ -526,8 +521,8 @@ proc Mix_SetPanning*(channel: int, left: Uint8, right: Uint8): int{.cdecl,
# * returns zero if error( no such channel or Mix_RegisterEffect( )fails ),
# * nonzero if position effect is enabled.
# * Error messages can be retrieved from Mix_GetError( ).
# *
proc Mix_SetPosition*(channel: int, angle: Sint16, distance: Uint8): int{.cdecl,
# *
proc Mix_SetPosition*(channel: int, angle: Sint16, distance: Uint8): int{.cdecl,
importc, dynlib: SDL_MixerLibName.}
#* set the "distance" of a channel.( distance ) is an integer from 0 to 255
# * that specifies the location of the sound in relation to the listener.
@ -555,8 +550,8 @@ proc Mix_SetPosition*(channel: int, angle: Sint16, distance: Uint8): int{.cdecl,
# * returns zero if error( no such channel or Mix_RegisterEffect( )fails ),
# * nonzero if position effect is enabled.
# * Error messages can be retrieved from Mix_GetError( ).
# *
proc Mix_SetDistance*(channel: int, distance: Uint8): int{.cdecl,
# *
proc Mix_SetDistance*(channel: int, distance: Uint8): int{.cdecl,
importc, dynlib: SDL_MixerLibName.}
# *
# * !!! FIXME : Haven't implemented, since the effect goes past the
@ -600,39 +595,39 @@ proc Mix_SetDistance*(channel: int, distance: Uint8): int{.cdecl,
# * nonzero if reversing effect is enabled.Note that an audio device in mono
# * mode is a no - op, but this call will return successful in that case .
# * Error messages can be retrieved from Mix_GetError( ).
# *
proc Mix_SetReverseStereo*(channel: int, flip: int): int{.cdecl,
# *
proc Mix_SetReverseStereo*(channel: int, flip: int): int{.cdecl,
importc, dynlib: SDL_MixerLibName.}
# end of effects API. - -ryan. *
# Reserve the first channels (0 -> n-1) for the application, i.e. don't allocate
# them dynamically to the next sample if requested with a -1 value below.
# Returns the number of reserved channels.
#
#
proc Mix_ReserveChannels*(num: int): int{.cdecl, importc, dynlib: SDL_MixerLibName.}
# Channel grouping functions
# Channel grouping functions
# Attach a tag to a channel. A tag can be assigned to several mixer
# channels, to form groups of channels.
# If 'tag' is -1, the tag is removed (actually -1 is the tag used to
# represent the group of all the channels).
# Returns true if everything was OK.
#
proc Mix_GroupChannel*(which: int, tag: int): int{.cdecl,
#
proc Mix_GroupChannel*(which: int, tag: int): int{.cdecl,
importc, dynlib: SDL_MixerLibName.}
# Assign several consecutive channels to a group
proc Mix_GroupChannels*(`from`: int, `to`: int, tag: int): int{.cdecl,
# Assign several consecutive channels to a group
proc Mix_GroupChannels*(`from`: int, `to`: int, tag: int): int{.cdecl,
importc, dynlib: SDL_MixerLibName.}
# Finds the first available channel in a group of channels
# Finds the first available channel in a group of channels
proc Mix_GroupAvailable*(tag: int): int{.cdecl, importc, dynlib: SDL_MixerLibName.}
# Returns the number of channels in a group. This is also a subtle
# way to get the total number of channels when 'tag' is -1
#
#
proc Mix_GroupCount*(tag: int): int{.cdecl, importc, dynlib: SDL_MixerLibName.}
# Finds the "oldest" sample playing in a group of channels
# Finds the "oldest" sample playing in a group of channels
proc Mix_GroupOldest*(tag: int): int{.cdecl, importc, dynlib: SDL_MixerLibName.}
# Finds the "most recent" (i.e. last) sample playing in a group of channels
# Finds the "most recent" (i.e. last) sample playing in a group of channels
proc Mix_GroupNewer*(tag: int): int{.cdecl, importc, dynlib: SDL_MixerLibName.}
# The same as above, but the sound is played at most 'ticks' milliseconds
proc Mix_PlayChannelTimed*(channel: int, chunk: PMix_Chunk, loops: int,
# The same as above, but the sound is played at most 'ticks' milliseconds
proc Mix_PlayChannelTimed*(channel: int, chunk: PMix_Chunk, loops: int,
ticks: int): int{.cdecl, importc, dynlib: SDL_MixerLibName.}
# Play an audio chunk on a specific channel.
# If the specified channel is -1, play on the first free channel.
@ -641,13 +636,13 @@ proc Mix_PlayChannelTimed*(channel: int, chunk: PMix_Chunk, loops: int,
# Returns which channel was used to play the sound.
#
proc Mix_PlayChannel*(channel: int, chunk: PMix_Chunk, loops: int): int
proc Mix_PlayMusic*(music: PMix_Music, loops: int): int{.cdecl,
proc Mix_PlayMusic*(music: PMix_Music, loops: int): int{.cdecl,
importc, dynlib: SDL_MixerLibName.}
# Fade in music or a channel over "ms" milliseconds, same semantics as the "Play" functions
proc Mix_FadeInMusic*(music: PMix_Music, loops: int, ms: int): int{.cdecl,
# Fade in music or a channel over "ms" milliseconds, same semantics as the "Play" functions
proc Mix_FadeInMusic*(music: PMix_Music, loops: int, ms: int): int{.cdecl,
importc, dynlib: SDL_MixerLibName.}
proc Mix_FadeInChannelTimed*(channel: int, chunk: PMix_Chunk, loops: int,
ms: int, ticks: int): int{.cdecl,
proc Mix_FadeInChannelTimed*(channel: int, chunk: PMix_Chunk, loops: int,
ms: int, ticks: int): int{.cdecl,
importc, dynlib: SDL_MixerLibName.}
proc Mix_FadeInChannel*(channel: int, chunk: PMix_Chunk, loops: int, ms: int): int
# Set the volume in the range of 0-128 of a specific channel or chunk.
@ -655,12 +650,12 @@ proc Mix_FadeInChannel*(channel: int, chunk: PMix_Chunk, loops: int, ms: int): i
# Returns the original volume.
# If the specified volume is -1, just return the current volume.
#
proc Mix_Volume*(channel: int, volume: int): int{.cdecl,
proc Mix_Volume*(channel: int, volume: int): int{.cdecl,
importc, dynlib: SDL_MixerLibName.}
proc Mix_VolumeChunk*(chunk: PMix_Chunk, volume: int): int{.cdecl,
proc Mix_VolumeChunk*(chunk: PMix_Chunk, volume: int): int{.cdecl,
importc, dynlib: SDL_MixerLibName.}
proc Mix_VolumeMusic*(volume: int): int{.cdecl, importc, dynlib: SDL_MixerLibName.}
# Halt playing of a particular channel
# Halt playing of a particular channel
proc Mix_HaltChannel*(channel: int): int{.cdecl, importc, dynlib: SDL_MixerLibName.}
proc Mix_HaltGroup*(tag: int): int{.cdecl, importc, dynlib: SDL_MixerLibName.}
proc Mix_HaltMusic*(): int{.cdecl, importc, dynlib: SDL_MixerLibName.}
@ -668,25 +663,25 @@ proc Mix_HaltMusic*(): int{.cdecl, importc, dynlib: SDL_MixerLibName.}
# The sample will stop playing after the 'ticks' milliseconds have elapsed,
# or remove the expiration if 'ticks' is -1
#
proc Mix_ExpireChannel*(channel: int, ticks: int): int{.cdecl,
proc Mix_ExpireChannel*(channel: int, ticks: int): int{.cdecl,
importc, dynlib: SDL_MixerLibName.}
# Halt a channel, fading it out progressively till it's silent
# The ms parameter indicates the number of milliseconds the fading
# will take.
#
proc Mix_FadeOutChannel*(which: int, ms: int): int{.cdecl,
#
proc Mix_FadeOutChannel*(which: int, ms: int): int{.cdecl,
importc, dynlib: SDL_MixerLibName.}
proc Mix_FadeOutGroup*(tag: int, ms: int): int{.cdecl, importc, dynlib: SDL_MixerLibName.}
proc Mix_FadeOutMusic*(ms: int): int{.cdecl, importc, dynlib: SDL_MixerLibName.}
# Query the fading status of a channel
# Query the fading status of a channel
proc Mix_FadingMusic*(): TMix_Fading{.cdecl, importc, dynlib: SDL_MixerLibName.}
proc Mix_FadingChannel*(which: int): TMix_Fading{.cdecl,
proc Mix_FadingChannel*(which: int): TMix_Fading{.cdecl,
importc, dynlib: SDL_MixerLibName.}
# Pause/Resume a particular channel
# Pause/Resume a particular channel
proc Mix_Pause*(channel: int){.cdecl, importc, dynlib: SDL_MixerLibName.}
proc Mix_Resume*(channel: int){.cdecl, importc, dynlib: SDL_MixerLibName.}
proc Mix_Paused*(channel: int): int{.cdecl, importc, dynlib: SDL_MixerLibName.}
# Pause/Resume the music stream
# Pause/Resume the music stream
proc Mix_PauseMusic*(){.cdecl, importc, dynlib: SDL_MixerLibName.}
proc Mix_ResumeMusic*(){.cdecl, importc, dynlib: SDL_MixerLibName.}
proc Mix_RewindMusic*(){.cdecl, importc, dynlib: SDL_MixerLibName.}
@ -697,16 +692,16 @@ proc Mix_PausedMusic*(): int{.cdecl, importc, dynlib: SDL_MixerLibName.}
# order number) and for OGG music (set position in seconds), at the
# moment.
#
proc Mix_SetMusicPosition*(position: float64): int{.cdecl,
proc Mix_SetMusicPosition*(position: float64): int{.cdecl,
importc, dynlib: SDL_MixerLibName.}
# Check the status of a specific channel.
# If the specified channel is -1, check all channels.
#
proc Mix_Playing*(channel: int): int{.cdecl, importc, dynlib: SDL_MixerLibName.}
proc Mix_PlayingMusic*(): int{.cdecl, importc, dynlib: SDL_MixerLibName.}
# Stop music and set external music playback command
# Stop music and set external music playback command
proc Mix_SetMusicCMD*(command: cstring): int{.cdecl, importc, dynlib: SDL_MixerLibName.}
# Synchro value is set by MikMod from modules while playing
# Synchro value is set by MikMod from modules while playing
proc Mix_SetSynchroValue*(value: int): int{.cdecl, importc, dynlib: SDL_MixerLibName.}
proc Mix_GetSynchroValue*(): int{.cdecl, importc, dynlib: SDL_MixerLibName.}
#
@ -714,29 +709,29 @@ proc Mix_GetSynchroValue*(): int{.cdecl, importc, dynlib: SDL_MixerLibName.}
# Returns nil if it's an invalid channel, or there's no chunk associated.
#
proc Mix_GetChunk*(channel: int): PMix_Chunk{.cdecl, importc, dynlib: SDL_MixerLibName.}
# Close the mixer, halting all playing audio
# Close the mixer, halting all playing audio
proc Mix_CloseAudio*(){.cdecl, importc, dynlib: SDL_MixerLibName.}
# We'll use SDL for reporting errors
# We'll use SDL for reporting errors
proc Mix_SetError*(fmt: cstring)
proc Mix_GetError*(): cstring
# implementation
proc SDL_MIXER_VERSION(X: var TSDL_version) =
proc SDL_MIXER_VERSION(X: var TSDL_version) =
X.major = SDL_MIXER_MAJOR_VERSION
X.minor = SDL_MIXER_MINOR_VERSION
X.patch = SDL_MIXER_PATCHLEVEL
proc Mix_LoadWAV(filename: cstring): PMix_Chunk =
proc Mix_LoadWAV(filename: cstring): PMix_Chunk =
result = Mix_LoadWAV_RW(SDL_RWFromFile(filename, "rb"), 1)
proc Mix_PlayChannel(channel: int, chunk: PMix_Chunk, loops: int): int =
proc Mix_PlayChannel(channel: int, chunk: PMix_Chunk, loops: int): int =
result = Mix_PlayChannelTimed(channel, chunk, loops, - 1)
proc Mix_FadeInChannel(channel: int, chunk: PMix_Chunk, loops: int, ms: int): int =
proc Mix_FadeInChannel(channel: int, chunk: PMix_Chunk, loops: int, ms: int): int =
result = Mix_FadeInChannelTimed(channel, chunk, loops, ms, - 1)
proc Mix_SetError(fmt: cstring) =
proc Mix_SetError(fmt: cstring) =
SDL_SetError(fmt)
proc Mix_GetError(): cstring =
proc Mix_GetError(): cstring =
result = SDL_GetError()

View file

@ -126,5 +126,5 @@ elif defined(mac):
nss = NSLookupSymbolInModule(NSModule(lib), name)
result = TProcAddr(NSAddressOfSymbol(nss))
else: # workaround a newly introduced bug :-(
else:
{.error: "no implementation for dyncalls".}

View file

@ -326,6 +326,9 @@ proc echo*(x: cstring) = ewriteln(x)
proc echo[Ty](x: Ty) =
echo(x)
proc echo[Ty](x: openArray[Ty]) =
for a in items(x): echo(a)
# Arithmetic:
proc addInt(a, b: int): int {.pure, compilerproc.} =
asm """

View file

@ -61,9 +61,6 @@ type
filename: CString
len: int # length of slots (when not debugging always zero)
TTempFrame = tuple[ # used for recursion elimination in WriteStackTrace
procname: CString, line: int]
var
buf: string # cannot be allocated on the stack!
assertBuf: string # we need a different buffer for
@ -72,33 +69,45 @@ var
framePtr {.exportc.}: PFrame
tempFrames: array [0..255, TTempFrame] # cannot be allocated
# on the stack!
tempFrames: array [0..127, PFrame] # cannot be allocated on the stack!
proc auxWriteStackTrace(f: PFrame, s: var string) =
const
firstCalls = 32
var
it = f
i = 0
total = 0
while it != nil and i <= high(tempFrames):
tempFrames[i] = (it.procname, it.line)
while it != nil and i <= high(tempFrames)-(firstCalls-1):
# the (-1) is for a nil entry that marks where the '...' should occur
tempFrames[i] = it
inc(i)
inc(total)
it = it.prev
var b = it
while it != nil:
inc(total)
it = it.prev
# if the buffer overflowed print '...':
for j in 1..total-i-(firstCalls-1):
if b != nil: b = b.prev
if total != i:
add(s, "(")
add(s, $(total-i))
add(s, " calls omitted) ...\n")
tempFrames[i] = nil
inc(i)
while b != nil and i <= high(tempFrames):
tempFrames[i] = b
inc(i)
b = b.prev
for j in countdown(i-1, 0):
add(s, $tempFrames[j].procname)
if tempFrames[j].line > 0:
add(s, ", line: ")
add(s, $tempFrames[j].line)
add(s, "\n")
if tempFrames[j] == nil:
add(s, "(")
add(s, $(total-i-1))
add(s, " calls omitted) ...\n")
else:
add(s, $tempFrames[j].procname)
if tempFrames[j].line > 0:
add(s, ", line: ")
add(s, $tempFrames[j].line)
add(s, "\n")
proc rawWriteStackTrace(s: var string) =
if framePtr == nil:
@ -156,8 +165,7 @@ proc internalAssert(file: cstring, line: int, cond: bool) {.compilerproc.} =
raise gAssertionFailed # newException(EAssertionFailed, assertBuf)
proc WriteStackTrace() =
var
s: string = ""
var s = ""
rawWriteStackTrace(s)
writeToStdErr(s)
@ -208,13 +216,13 @@ assertBuf = newString(2048)
setLen(buf, 0)
setLen(assertBuf, 0)
proc raiseRangeError(val: biggestInt) {.compilerproc, noreturn.} =
proc raiseRangeError(val: biggestInt) {.compilerproc, noreturn, noinline.} =
raise newException(EOutOfRange, "value " & $val & " out of range")
proc raiseIndexError() {.compilerproc, noreturn.} =
proc raiseIndexError() {.compilerproc, noreturn, noinline.} =
raise newException(EInvalidIndex, "index out of bounds")
proc raiseFieldError(f: string) {.compilerproc, noreturn.} =
proc raiseFieldError(f: string) {.compilerproc, noreturn, noinline.} =
raise newException(EInvalidField, f & " is not accessible")
proc chckIndx(i, a, b: int): int =

View file

@ -13,11 +13,10 @@
# * incremental
# * non-recursive
# * generational
# * excellent performance
# Future Improvements:
# * Both dlmalloc and TLSF lack zero-overhead object allocation. Thus, for
# small objects we will should use our own allocator.
# small objects we should use our own allocator.
# * Support for multi-threading. However, locks for the reference counting
# might turn out to be too slow.
@ -332,7 +331,7 @@ proc CellSetPut(t: var TCellSet, key: TAddress): PPageDesc =
# ---------- slightly higher level procs --------------------------------------
proc in_Operator(s: TCellSet, cell: PCell): bool =
proc contains(s: TCellSet, cell: PCell): bool =
var u = cast[TAddress](cell)
var t = CellSetGet(s, u shr PageShift)
if t != nil:
@ -468,23 +467,6 @@ proc prepareDealloc(cell: PCell) =
proc setStackBottom(theStackBottom: pointer) {.compilerproc.} =
stackBottom = theStackBottom
proc initGC() =
when traceGC:
for i in low(TCellState)..high(TCellState): CellSetInit(states[i])
gch.stackScans = 0
gch.cycleCollections = 0
gch.maxThreshold = 0
gch.maxStackSize = 0
gch.maxStackPages = 0
gch.cycleTableSize = 0
# init the rt
init(gch.zct)
init(gch.tempStack)
CellSetInit(gch.cycleRoots)
CellSetInit(gch.stackCells)
gch.mask = 0
new(gOutOfMem) # reserve space for the EOutOfMemory exception here!
proc PossibleRoot(gch: var TGcHeap, c: PCell) {.inline.} =
if canbeCycleRoot(c): incl(gch.cycleRoots, c)
@ -535,6 +517,23 @@ proc unsureAsgnRef(dest: ppointer, src: pointer) =
if dest^ != nil: decRef(usrToCell(dest^))
dest^ = src
proc initGC() =
when traceGC:
for i in low(TCellState)..high(TCellState): CellSetInit(states[i])
gch.stackScans = 0
gch.cycleCollections = 0
gch.maxThreshold = 0
gch.maxStackSize = 0
gch.maxStackPages = 0
gch.cycleTableSize = 0
# init the rt
init(gch.zct)
init(gch.tempStack)
CellSetInit(gch.cycleRoots)
CellSetInit(gch.stackCells)
gch.mask = 0
new(gOutOfMem) # reserve space for the EOutOfMemory exception here!
proc getDiscriminant(aa: Pointer, n: ptr TNimNode): int =
assert(n.kind == nkCase)
var d: int

View file

@ -151,8 +151,7 @@ proc open(L: var TBaseLexer, input: PStream, bufLen: int = 8192) =
skip_UTF_8_BOM(L)
proc getColNumber(L: TBaseLexer, pos: int): int =
result = pos - L.lineStart
assert(result >= 0)
result = abs(pos - L.lineStart)
proc getCurrentLine(L: TBaseLexer, marker: bool = true): string =
var i: int

View file

@ -30,59 +30,59 @@
# if key[-4:] == "Flag": continue
# cog.out(toEnum(key, val))
#]]]
type
TNimrodTypeKind* = enum
ntyNone, ntyBool, ntyChar, ntyEmpty,
ntyArrayConstr, ntyNil, ntyGeneric, ntyGenericInst,
ntyGenericParam, ntyEnum, ntyAnyEnum, ntyArray,
ntyObject, ntyTuple, ntySet, ntyRange,
ntyPtr, ntyRef, ntyVar, ntySequence,
ntyProc, ntyPointer, ntyOpenArray, ntyString,
ntyCString, ntyForward, ntyInt, ntyInt8,
ntyInt16, ntyInt32, ntyInt64, ntyFloat,
ntyFloat32, ntyFloat64, ntyFloat128
TNimTypeKinds* = set[TNimrodTypeKind]
TNimrodSymKind* = enum
nskUnknownSym, nskConditional, nskDynLib, nskParam,
nskTypeParam, nskTemp, nskType, nskConst,
nskVar, nskProc, nskIterator, nskConverter,
nskMacro, nskTemplate, nskField, nskEnumField,
nskForVar, nskModule, nskLabel, nskStub
TNimSymKinds* = set[TNimrodSymKind]
TNimrodNodeKind* = enum
nnkNone, nnkEmpty, nnkIdent, nnkSym,
nnkType, nnkCharLit, nnkIntLit, nnkInt8Lit,
nnkInt16Lit, nnkInt32Lit, nnkInt64Lit, nnkFloatLit,
nnkFloat32Lit, nnkFloat64Lit, nnkStrLit, nnkRStrLit,
nnkTripleStrLit, nnkMetaNode, nnkNilLit, nnkDotCall,
nnkCommand, nnkCall, nnkGenericCall, nnkExplicitTypeListCall,
nnkExprEqExpr, nnkExprColonExpr, nnkIdentDefs, nnkInfix,
nnkPrefix, nnkPostfix, nnkPar, nnkCurly,
nnkBracket, nnkBracketExpr, nnkPragmaExpr, nnkRange,
nnkDotExpr, nnkCheckedFieldExpr, nnkDerefExpr, nnkIfExpr,
nnkElifExpr, nnkElseExpr, nnkLambda, nnkAccQuoted,
nnkHeaderQuoted, nnkTableConstr, nnkQualified, nnkHiddenStdConv,
nnkHiddenSubConv, nnkHiddenCallConv, nnkConv, nnkCast,
nnkAddr, nnkHiddenAddr, nnkHiddenDeref, nnkObjDownConv,
nnkObjUpConv, nnkChckRangeF, nnkChckRange64, nnkChckRange,
nnkStringToCString, nnkCStringToString, nnkPassAsOpenArray, nnkAsgn,
nnkDefaultTypeParam, nnkGenericParams, nnkFormalParams, nnkOfInherit,
nnkModule, nnkProcDef, nnkConverterDef, nnkMacroDef,
nnkTemplateDef, nnkIteratorDef, nnkOfBranch, nnkElifBranch,
nnkExceptBranch, nnkElse, nnkMacroStmt, nnkAsmStmt,
nnkPragma, nnkIfStmt, nnkWhenStmt, nnkForStmt,
nnkWhileStmt, nnkCaseStmt, nnkVarSection, nnkConstSection,
nnkConstDef, nnkTypeSection, nnkTypeDef, nnkYieldStmt,
nnkTryStmt, nnkFinally, nnkRaiseStmt, nnkReturnStmt,
nnkBreakStmt, nnkContinueStmt, nnkBlockStmt, nnkDiscardStmt,
nnkStmtList, nnkImportStmt, nnkFromStmt, nnkImportAs,
nnkIncludeStmt, nnkAccessStmt, nnkCommentStmt, nnkStmtListExpr,
nnkBlockExpr, nnkStmtListType, nnkBlockType, nnkVm,
nnkTypeOfExpr, nnkObjectTy, nnkTupleTy, nnkRecList,
nnkRecCase, nnkRecWhen, nnkRefTy, nnkPtrTy,
nnkVarTy, nnkProcTy, nnkEnumTy, nnkEnumFieldDef,
nnkReturnToken
TNimNodeKinds* = set[TNimrodNodeKind]
type
TNimrodNodeKind* = enum
nnkNone, nnkEmpty, nnkIdent, nnkSym,
nnkType, nnkCharLit, nnkIntLit, nnkInt8Lit,
nnkInt16Lit, nnkInt32Lit, nnkInt64Lit, nnkFloatLit,
nnkFloat32Lit, nnkFloat64Lit, nnkStrLit, nnkRStrLit,
nnkTripleStrLit, nnkMetaNode, nnkNilLit, nnkDotCall,
nnkCommand, nnkCall, nnkGenericCall, nnkExplicitTypeListCall,
nnkExprEqExpr, nnkExprColonExpr, nnkIdentDefs, nnkVarTuple,
nnkInfix, nnkPrefix, nnkPostfix, nnkPar,
nnkCurly, nnkBracket, nnkBracketExpr, nnkPragmaExpr,
nnkRange, nnkDotExpr, nnkCheckedFieldExpr, nnkDerefExpr,
nnkIfExpr, nnkElifExpr, nnkElseExpr, nnkLambda,
nnkAccQuoted, nnkHeaderQuoted, nnkTableConstr, nnkQualified,
nnkHiddenStdConv, nnkHiddenSubConv, nnkHiddenCallConv, nnkConv,
nnkCast, nnkAddr, nnkHiddenAddr, nnkHiddenDeref,
nnkObjDownConv, nnkObjUpConv, nnkChckRangeF, nnkChckRange64,
nnkChckRange, nnkStringToCString, nnkCStringToString, nnkPassAsOpenArray,
nnkAsgn, nnkFastAsgn, nnkDefaultTypeParam, nnkGenericParams,
nnkFormalParams, nnkOfInherit, nnkModule, nnkProcDef,
nnkConverterDef, nnkMacroDef, nnkTemplateDef, nnkIteratorDef,
nnkOfBranch, nnkElifBranch, nnkExceptBranch, nnkElse,
nnkMacroStmt, nnkAsmStmt, nnkPragma, nnkIfStmt,
nnkWhenStmt, nnkForStmt, nnkWhileStmt, nnkCaseStmt,
nnkVarSection, nnkConstSection, nnkConstDef, nnkTypeSection,
nnkTypeDef, nnkYieldStmt, nnkTryStmt, nnkFinally,
nnkRaiseStmt, nnkReturnStmt, nnkBreakStmt, nnkContinueStmt,
nnkBlockStmt, nnkDiscardStmt, nnkStmtList, nnkImportStmt,
nnkFromStmt, nnkImportAs, nnkIncludeStmt, nnkAccessStmt,
nnkCommentStmt, nnkStmtListExpr, nnkBlockExpr, nnkStmtListType,
nnkBlockType, nnkVm, nnkTypeOfExpr, nnkObjectTy,
nnkTupleTy, nnkRecList, nnkRecCase, nnkRecWhen,
nnkRefTy, nnkPtrTy, nnkVarTy, nnkProcTy,
nnkEnumTy, nnkEnumFieldDef, nnkReturnToken
TNimNodeKinds* = set[TNimrodNodeKind]
TNimrodTypeKind* = enum
ntyNone, ntyBool, ntyChar, ntyEmpty,
ntyArrayConstr, ntyNil, ntyGeneric, ntyGenericInst,
ntyGenericParam, ntyEnum, ntyAnyEnum, ntyArray,
ntyObject, ntyTuple, ntySet, ntyRange,
ntyPtr, ntyRef, ntyVar, ntySequence,
ntyProc, ntyPointer, ntyOpenArray, ntyString,
ntyCString, ntyForward, ntyInt, ntyInt8,
ntyInt16, ntyInt32, ntyInt64, ntyFloat,
ntyFloat32, ntyFloat64, ntyFloat128
TNimTypeKinds* = set[TNimrodTypeKind]
TNimrodSymKind* = enum
nskUnknownSym, nskConditional, nskDynLib, nskParam,
nskTypeParam, nskTemp, nskType, nskConst,
nskVar, nskProc, nskIterator, nskConverter,
nskMacro, nskTemplate, nskField, nskEnumField,
nskForVar, nskModule, nskLabel, nskStub
TNimSymKinds* = set[TNimrodSymKind]
#[[[end]]]
type

View file

@ -421,18 +421,4 @@ struct NimException {
};
#endif
#if 0
typedef struct TStringDesc {
NI len;
NI space;
NIM_CHAR data[1]; /* SEQ_DECL_SIZE]; */
} TStringDesc;
typedef struct {
NI len, space;
} TGenericSeq;
typedef TGenericSeq* PGenericSeq;
#endif
#endif

View file

@ -11,6 +11,7 @@
## retrieving environment variables, reading command line arguments,
## working with directories, running shell commands, etc.
## This module is -- like any other basic library -- platform independant.
{.deadCodeElim: on.}
{.push debugger: off.}
@ -863,9 +864,9 @@ var
when defined(windows):
# because we support Windows GUI applications, things get really
# messy here...
proc GetEnvironmentStringsA*(): cstring {.
proc GetEnvironmentStringsA(): cstring {.
stdcall, dynlib: "kernel32", importc.}
proc FreeEnvironmentStringsA*(para1: cstring): int32 {.
proc FreeEnvironmentStringsA(para1: cstring): int32 {.
stdcall, dynlib: "kernel32", importc.}
proc strEnd(cstr: CString, c = 0): CString {.importc: "strchr", nodecl.}
@ -1091,8 +1092,8 @@ proc expandFilename(filename: string): string =
proc parseCmdLine*(c: string): seq[string] =
## Splits a command line into several components; components are separated by
## whitespace or are quoted with the ``"`` or ``'`` characters. This proc is
## only occassionally useful, better use the `parseopt` module.
## whitespace unless the whitespace occurs within ``"`` or ``'`` quotes.
## This proc is only occassionally useful, better use the `parseopt` module.
result = @[]
var i = 0
while c[i] != '\0':

View file

@ -54,7 +54,7 @@ type
TTokKind = enum
tkInvalid, tkEof,
tkSymbol, tkEquals, tkColon, tkBracketLe, tkBracketRi, tkDashDash
TToken{.final.} = object # a token
TToken {.final.} = object # a token
kind: TTokKind # the type of the token
literal: string # the parsed (string) literal
@ -139,7 +139,7 @@ proc getEscapedChar(c: var TCfgParser, tok: var TToken) =
inc(c.bufpos) # skip '\'
case c.buf[c.bufpos]
of 'n', 'N':
tok.literal = tok.literal & nl
add(tok.literal, nl)
Inc(c.bufpos)
of 'r', 'R', 'c', 'C':
add(tok.literal, '\c')

View file

@ -53,7 +53,7 @@ proc init(cmdline: string = ""): TOptParser =
else:
result.cmd = ""
for i in countup(1, ParamCount()):
result.cmd = result.cmd & quoteIfSpaceExists(paramStr(i)) & ' '
result.cmd = result.cmd & quoteIfContainsWhite(paramStr(i)) & ' '
result.kind = cmdEnd
result.key = ""
result.val = ""

View file

@ -22,12 +22,12 @@ proc reprPointer(x: pointer): string {.compilerproc.} =
proc reprStrAux(result: var string, s: string) =
if cast[pointer](s) == nil:
add result "nil"
add result, "nil"
return
add result, reprPointer(cast[pointer](s)) & "\""
for c in items(s):
case c
of '"': add result "\\\""
of '"': add result, "\\\""
of '\\': add result, "\\\\" # BUGFIX: forgotten
of '\10': add result, "\\10\"\n\"" # " \n " # better readability
of '\128' .. '\255', '\0'..'\9', '\11'..'\31':

View file

@ -12,6 +12,8 @@
## All the routines here are avaiable for the EMCAScript target
## too!
{.deadCodeElim: on.}
{.push debugger:off .} # the user does not want to trace a part
# of the standard library!
@ -41,19 +43,19 @@ proc strip*(s: string): string {.noSideEffect.}
proc toLower*(s: string): string {.noSideEffect.}
## Converts `s` into lower case. This works only for the letters A-Z.
## See `charsets.nativeToLower` for a version that is locale-dependant.
## See `unicode.toLower` for a version that works for any Unicode character.
proc toLower*(c: Char): Char {.noSideEffect.}
## Converts `c` into lower case. This works only for the letters A-Z.
## See `charsets.nativeToLower()` for a version that is locale-dependant.
## See `unicode.toLower` for a version that works for any Unicode character.
proc toUpper*(s: string): string {.noSideEffect.}
## Converts `s` into upper case. This works only for the letters a-z.
## See `charsets.nativeToUpper()` for a version that is locale-dependant.
## See `unicode.toUpper` for a version that works for any Unicode character.
proc toUpper*(c: Char): Char {.noSideEffect.}
## Converts `c` into upper case. This works only for the letters a-z.
## See `charsets.nativeToUpper()` for a version that is locale-dependant.
## See `unicode.toUpper` for a version that works for any Unicode character.
proc capitalize*(s: string): string {.noSideEffect.}
## Converts the first character of `s` into upper case.
@ -71,6 +73,10 @@ proc findSubStr*(sub: char, s: string, start: int = 0): int {.noSideEffect.}
## Searches for `sub` in `s` starting at position `start`. Searching is
## case-sensitive. If `sub` is not in `s`, -1 is returned.
proc findChars*(chars: set[char], s: string, start: int = 0): int {.noSideEffect.}
## Searches for `chars` in `s` starting at position `start`. If `s` contains
## none of the characters in `chars`, -1 is returned.
proc replaceStr*(s, sub, by: string): string {.noSideEffect.}
## Replaces `sub` in `s` by the string `by`.
@ -173,11 +179,14 @@ proc cmpIgnoreStyle*(a, b: string): int {.noSideEffect.}
## | < 0 iff a < b
## | > 0 iff a > b
proc in_Operator*(s: string, c: char): bool {.noSideEffect.}
## Same as `findSubStr(c, s) >= 0`.
proc contains*(s: string, c: char): bool {.noSideEffect.}
## Same as ``findSubStr(c, s) >= 0``.
proc in_Operator*(s, sub: string): bool {.noSideEffect.}
## Same as `findSubStr(sub, s) >= 0`.
proc contains*(s, sub: string): bool {.noSideEffect.}
## Same as ``findSubStr(sub, s) >= 0``.
proc contains*(s: string, chars: set[char]): bool {.noSideEffect.}
## Same as ``findChars(s, chars) >= 0``.
proc toHex*(x: BiggestInt, len: int): string {.noSideEffect.}
## Converts `x` to its hexadecimal representation. The resulting string
@ -259,10 +268,10 @@ proc allCharsInSet*(s: string, theSet: TCharSet): bool =
if not (c in theSet): return false
return true
proc quoteIfSpaceExists*(s: string): string =
proc quoteIfContainsWhite*(s: string): string =
## returns ``'"' & s & '"'`` if `s` contains a space and does not
## start with a quote, else returns `s`
if findSubStr(' ', s) >= 0 and s[0] != '"':
if findChars({' ', '\t'}, s) >= 0 and s[0] != '"':
result = '"' & s & '"'
else:
result = s
@ -488,11 +497,19 @@ proc findSubStr(sub: char, s: string, start: int = 0): int =
for i in start..len(s)-1:
if sub == s[i]: return i
return -1
proc findChars(chars: set[char], s: string, start: int = 0): int =
for i in start..s.len-1:
if s[i] in chars: return i
return -1
proc contains(s: string, chars: set[char]): bool =
return findChars(chars, s) >= 0
proc in_Operator(s: string, c: char): bool =
proc contains(s: string, c: char): bool =
return findSubStr(c, s) >= 0
proc in_Operator(s, sub: string): bool =
proc contains(s, sub: string): bool =
return findSubStr(sub, s) >= 0
proc replaceStr(s, sub, by: string): string =

View file

@ -91,10 +91,13 @@ proc writeln[Ty](f: TFile, x: Ty) =
write(f, "\n")
proc writeln[Ty](f: TFile, x: openArray[Ty]) =
write(f, x)
for i in items(x): write(f, i)
write(f, "\n")
proc echo[Ty](x: Ty) = writeln(stdout, x)
proc echo[Ty](x: openArray[Ty]) =
for i in items(x): write(stdout, i)
write(stdout, "\n")
# interface to the C procs:
proc fopen(filename, mode: CString): pointer {.importc: "fopen", noDecl.}

View file

@ -15,13 +15,6 @@
# we don't use refcounts because that's a behaviour
# the programmer may not want
type
# len and space without counting the terminating zero:
NimStringDesc {.compilerproc, final.} = object of TGenericSeq
data: array[0..100_000_000, char] # for the '\0' character
NimString = ptr NimStringDesc
# implementation:
proc resize(old: int): int {.inline.} =

View file

@ -58,6 +58,17 @@ proc defined*[T] (x: T): bool {.magic: "Defined", noSideEffect.}
proc `not` *(x: bool): bool {.magic: "Not", noSideEffect.}
## Boolean not; returns true iff ``x == false``.
proc `and`*(x, y: bool): bool {.magic: "And", noSideEffect.}
## Boolean ``and``; returns true iff ``x == y == true``.
## Evaluation is short-circuited: This means that if ``x`` is false,
## ``y`` will not even be evaluated.
proc `or`*(x, y: bool): bool {.magic: "Or", noSideEffect.}
## Boolean ``or``; returns true iff ``not (not x and not y)``.
## Evaluation is short-circuited: This means that if ``x`` is true,
## ``y`` will not even be evaluated.
proc `xor`*(x, y: bool): bool {.magic: "Xor", noSideEffect.}
## Boolean `exclusive or`; returns true iff ``x != y``.
proc new*[T](a: var ref T) {.magic: "New".}
## creates a new object of type ``T`` and returns a safe (traced)
## reference to it in ``a``.
@ -94,6 +105,19 @@ type
seq*{.magic: "Seq".}[T] ## Generic type to construct sequences.
set*{.magic: "Set".}[T] ## Generic type to construct bit sets.
when not defined(EcmaScript) and not defined(NimrodVM):
type
TGenericSeq {.compilerproc, pure.} = object
len, space: int
PGenericSeq {.exportc.} = ptr TGenericSeq
# len and space without counting the terminating zero:
NimStringDesc {.compilerproc, final.} = object of TGenericSeq
data: array[0..100_000_000, char]
NimString = ptr NimStringDesc
include hti
type
Byte* = Int8 ## this is an alias for ``int8``, that is a signed
## int 8 bits wide.
@ -403,8 +427,8 @@ proc abs*(x: int8): int8 {.magic: "AbsI", noSideEffect.}
proc abs*(x: int16): int16 {.magic: "AbsI", noSideEffect.}
proc abs*(x: int32): int32 {.magic: "AbsI", noSideEffect.}
proc abs*(x: int64): int64 {.magic: "AbsI64", noSideEffect.}
## returns the absolute value of `x`. If `x` is ``low(x)`` (that is
## -MININT for its type), an overflow exception is thrown (if overflow
## returns the absolute value of `x`. If `x` is ``low(x)`` (that
## is -MININT for its type), an overflow exception is thrown (if overflow
## checking is turned on).
proc min*(x, y: int): int {.magic: "MinI", noSideEffect.}
@ -500,18 +524,6 @@ proc abs*(x: float): float {.magic: "AbsF64", noSideEffect.}
proc min*(x, y: float): float {.magic: "MinF64", noSideEffect.}
proc max*(x, y: float): float {.magic: "MaxF64", noSideEffect.}
# boolean operators:
proc `and`*(x, y: bool): bool {.magic: "And", noSideEffect.}
## Boolean ``and``; returns true iff ``x == y == true``.
## Evaluation is short-circuited: This means that if ``x`` is false,
## ``y`` will not even be evaluated.
proc `or`*(x, y: bool): bool {.magic: "Or", noSideEffect.}
## Boolean ``or``; returns true iff ``not (not x and not y)``.
## Evaluation is short-circuited: This means that if ``x`` is true,
## ``y`` will not even be evaluated.
proc `xor`*(x, y: bool): bool {.magic: "Xor", noSideEffect.}
## Boolean `exclusive or`; returns true iff ``x != y``.
# set operators
proc `*` *[T](x, y: set[T]): set[T] {.magic: "MulSet", noSideEffect.}
## This operator computes the intersection of two sets.
@ -563,11 +575,12 @@ template `>` * (x, y: expr): expr =
## "is greater" operator. This is the same as ``y < x``.
y < x
proc in_Operator*[T](x: set[T], y: T): bool {.magic: "InSet", noSideEffect.}
proc contains*[T](x: set[T], y: T): bool {.magic: "InSet", noSideEffect.}
## One should overload this proc if one wants to overload the ``in`` operator.
## The parameters are in reverse order! This is because the unification
## algorithm that Nimrod uses for overload resolution works from left to
## right.
## The parameters are in reverse order! ``a in b`` is a template for
## ``contains(b, a)``.
## This is because the unification algorithm that Nimrod uses for overload
## resolution works from left to right.
## But for the ``in`` operator that would be the wrong direction for this
## piece of code:
##
@ -578,11 +591,11 @@ proc in_Operator*[T](x: set[T], y: T): bool {.magic: "InSet", noSideEffect.}
## If ``in`` had been declared as ``[T](elem: T, s: set[T])`` then ``T`` would
## have been bound to ``char``. But ``s`` is not compatible to type
## ``set[char]``! The solution is to bind ``T`` to ``range['a'..'z']``. This
## is achieved by reversing the parameters for ``in_operator``; ``in`` then
## is achieved by reversing the parameters for ``contains``; ``in`` then
## passes its arguments in reverse order.
template `in` * (x, y: expr): expr = in_Operator(y, x)
template `not_in` * (x, y: expr): expr = not in_Operator(y, x)
template `in` * (x, y: expr): expr = contains(y, x)
template `not_in` * (x, y: expr): expr = not contains(y, x)
proc `is` *[T, S](x: T, y: S): bool {.magic: "Is", noSideEffect.}
template `is_not` *(x, y: expr): expr = not (x is y)
@ -616,15 +629,17 @@ proc `&` * (x: char, y: string): string {.
magic: "ConStrStr", noSideEffect, merge.}
## is the `concatenation operator`. It concatenates `x` and `y`.
proc add * (x: var string, y: char) {.magic: "AppendStrCh".}
proc add * (x: var string, y: string) {.magic: "AppendStrStr".}
proc add*(x: var string, y: char) {.magic: "AppendStrCh".}
proc add*(x: var string, y: string) {.magic: "AppendStrStr".}
when not defined(ECMAScript):
{.push overflow_checks:off}
proc add* (x: var string, y: cstring) =
var i = 0
while y[i] != '\0':
add(x, y[i])
inc(i)
{.pop.}
else:
proc add* (x: var string, y: cstring) {.pure.} =
asm """
@ -646,7 +661,7 @@ proc add *[T](x: var seq[T], y: seq[T]) {.magic: "AppendSeqSeq".}
proc repr*[T](x: T): string {.magic: "Repr", noSideEffect.}
## takes any Nimrod variable and returns its string representation. It
## works even for complex data graphs with cycles. This is an invaluable
## works even for complex data graphs with cycles. This is a great
## debugging tool.
type
@ -729,7 +744,16 @@ const
cpuEndian* {.magic: "CpuEndian"}: TEndian = littleEndian
## is the endianness of the target CPU. This is a valuable piece of
## information for low-level code only. This works thanks to compiler magic.
hostOS* {.magic: "HostOS"}: string = ""
## a string that describes the host operating system. Possible values:
## "windows", "macosx", "linux", "netbsd", "freebsd", "openbsd", "solaris",
## "aix"
hostCPU* {.magic: "HostCPU"}: string = ""
## a string that describes the host CPU. Possible values:
## "i386", "alpha", "powerpc", "sparc", "amd64", "mips", "arm"
proc toFloat*(i: int): float {.
magic: "ToFloat", noSideEffect, importc: "toFloat".}
## converts an integer `i` into a ``float``. If the conversion
@ -896,6 +920,12 @@ proc `$` *(x: string): string {.magic: "StrToStr", noSideEffect.}
## as it is. This operator is useful for generic code, so
## that ``$expr`` also works if ``expr`` is already a string.
proc `$` *(x: TAnyEnum): string {.magic: "EnumToStr", noSideEffect.}
## The stingify operator for an enumeration argument. This works for
## any enumeration type thanks to compiler magic. If a
## a ``$`` operator for a concrete enumeration is provided, this is
## used instead. (In other words: *Overwriting* is possible.)
# undocumented:
proc getRefcount*[T](x: ref T): int {.importc: "getRefcount".}
## retrieves the reference count of an heap-allocated object. The
@ -1136,6 +1166,10 @@ proc echo*[Ty](x: Ty) {.inline.}
## equivalent to ``writeln(stdout, x); flush(stdout)``. BUT: This is
## available for the ECMAScript target too!
proc echo*[Ty](x: openarray[Ty]) {.inline.}
## equivalent to ``writeln(stdout, x); flush(stdout)``. BUT: This is
## available for the ECMAScript target too!
template newException(exceptn, message: expr): expr =
block: # open a new scope
@ -1169,8 +1203,6 @@ when not defined(EcmaScript) and not defined(NimrodVM):
when not defined(EcmaScript) and not defined(NimrodVM):
include hti
proc initGC()
var
@ -1370,13 +1402,6 @@ when not defined(EcmaScript) and not defined(NimrodVM):
include arithm
{.pop.} # stack trace
# sequence type declarations here because the GC needs them too:
type
TGenericSeq {.compilerproc, pure.} = object
len, space: int
PGenericSeq {.exportc.} = ptr TGenericSeq
const
GenericSeqSize = (2 * sizeof(int))
@ -1417,13 +1442,12 @@ elif defined(NimrodVM):
proc getFreeMem(): int = return -1
proc getTotalMem(): int = return -1
proc echo[Ty](x: Ty) = nil
proc echo[Ty](x: openarray[Ty]) = nil
proc cmp(x, y: string): int =
if x == y: return 0
if x < y: return -1
return 1
include macros
{.pop.} # checks
{.pop.} # hints

View file

@ -276,8 +276,8 @@ else:
proc getDateStr(): string =
var ti = getLocalTime(getTime())
result = $ti.year & "-" & intToStr(ord(ti.month)+1, 2) &
"-" & intToStr(ti.monthDay, 2)
result = $ti.year & '-' & intToStr(ord(ti.month)+1, 2) &
'-' & intToStr(ti.monthDay, 2)
proc getClockStr(): string =
var ti = getLocalTime(getTime())

File diff suppressed because it is too large Load diff

View file

@ -10,6 +10,8 @@
## Define ``winUnicode`` before importing this module for the
## unicode version.
{.deadCodeElim: on.}
type
ATOM* = int16
TAtom* = ATOM