too many changes to list
This commit is contained in:
parent
916c25f9a7
commit
07d5a8085b
200 changed files with 24344 additions and 17809 deletions
|
|
@ -2,6 +2,10 @@
|
||||||
# (c) 2008 Andreas Rumpf
|
# (c) 2008 Andreas Rumpf
|
||||||
# Feel free to edit the templates as you need.
|
# Feel free to edit the templates as you need.
|
||||||
|
|
||||||
|
split.item.toc = "25"
|
||||||
|
# too long entries in the table of contents get truncated
|
||||||
|
# after this number of characters
|
||||||
|
|
||||||
doc.section = """
|
doc.section = """
|
||||||
<div class="section" id="$sectionID">
|
<div class="section" id="$sectionID">
|
||||||
<h1><a class="toc-backref" href="#$sectionTitleID">$sectionTitle</a></h1>
|
<h1><a class="toc-backref" href="#$sectionTitleID">$sectionTitle</a></h1>
|
||||||
|
|
@ -52,10 +56,10 @@ $content
|
||||||
"""
|
"""
|
||||||
|
|
||||||
doc.file = """<?xml version="1.0" encoding="utf-8" ?>
|
doc.file = """<?xml version="1.0" encoding="utf-8" ?>
|
||||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
|
||||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
|
||||||
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||||||
<!-- This file is generated by Nimrod. -->
|
<!-- This file is generated by Nimrod. -->
|
||||||
|
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||||
<title>$title</title>
|
<title>$title</title>
|
||||||
|
|
@ -88,7 +92,7 @@ span.Command, span.Rule, span.Hyperlink, span.Label, span.Reference,
|
||||||
span.Other {color: black}
|
span.Other {color: black}
|
||||||
|
|
||||||
div.navigation {
|
div.navigation {
|
||||||
float: left; width: 20em;
|
float: left; width: 25em;
|
||||||
margin: 0; padding: 0; /*
|
margin: 0; padding: 0; /*
|
||||||
border: 1px dashed gold; */
|
border: 1px dashed gold; */
|
||||||
outline: 3px outset #99ff99; //gold;
|
outline: 3px outset #99ff99; //gold;
|
||||||
|
|
@ -109,7 +113,7 @@ div.navigation ul li a:hover {
|
||||||
}
|
}
|
||||||
|
|
||||||
div.content {
|
div.content {
|
||||||
margin-left: 20em;
|
margin-left: 25em;
|
||||||
padding: 0 1em;
|
padding: 0 1em;
|
||||||
border: 1px dashed gold;
|
border: 1px dashed gold;
|
||||||
min-width: 16em;
|
min-width: 16em;
|
||||||
|
|
@ -285,4 +289,3 @@ $content
|
||||||
</html>
|
</html>
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@write "used doctempl.cfg"
|
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@
|
||||||
# Environment variables cannot be used in the options, however!
|
# Environment variables cannot be used in the options, however!
|
||||||
|
|
||||||
# Just call the compiler with several options:
|
# Just call the compiler with several options:
|
||||||
cc = @if unix: gcc @else: llvm_gcc @end
|
cc = @if unix: gcc @else: vcc @end
|
||||||
lib="$nimrod/lib"
|
lib="$nimrod/lib"
|
||||||
path="$lib/base"
|
path="$lib/base"
|
||||||
path="$lib/base/gtk"
|
path="$lib/base/gtk"
|
||||||
|
|
@ -17,13 +17,22 @@ path="$lib/base/cairo"
|
||||||
path="$lib/base/x11"
|
path="$lib/base/x11"
|
||||||
path="$lib/windows"
|
path="$lib/windows"
|
||||||
path="$lib/posix"
|
path="$lib/posix"
|
||||||
|
path="$lib/ecmas"
|
||||||
path="$lib/extra"
|
path="$lib/extra"
|
||||||
|
|
||||||
|
@if release:
|
||||||
|
checks:off
|
||||||
|
stacktrace:off
|
||||||
|
debugger:off
|
||||||
|
line_dir:off
|
||||||
|
@end
|
||||||
|
|
||||||
# additional defines:
|
# additional defines:
|
||||||
#define=""
|
#define=""
|
||||||
# additional options always passed to the compiler:
|
# additional options always passed to the compiler:
|
||||||
force_build
|
force_build
|
||||||
line_dir=off
|
line_dir=off
|
||||||
|
cfilecache=on
|
||||||
|
|
||||||
hint[LineTooLong]=off
|
hint[LineTooLong]=off
|
||||||
hint[XDeclaredButNotUsed]=off
|
hint[XDeclaredButNotUsed]=off
|
||||||
|
|
@ -40,7 +49,7 @@ hint[XDeclaredButNotUsed]=off
|
||||||
|
|
||||||
# Configuration for the LLVM GCC compiler:
|
# Configuration for the LLVM GCC compiler:
|
||||||
@if windows:
|
@if windows:
|
||||||
llvm_gcc.path = r"dist\llvm-gcc4.2\bin"
|
llvm_gcc.path = r"$nimrod\dist\llvm-gcc4.2\bin"
|
||||||
@end
|
@end
|
||||||
llvm_gcc.options.debug = "-g"
|
llvm_gcc.options.debug = "-g"
|
||||||
llvm_gcc.options.always = "-w"
|
llvm_gcc.options.always = "-w"
|
||||||
|
|
@ -59,14 +68,15 @@ bcc.options.size = "-O1 -6"
|
||||||
|
|
||||||
# Configuration for the Visual C/C++ compiler:
|
# Configuration for the Visual C/C++ compiler:
|
||||||
@if vcc:
|
@if vcc:
|
||||||
@prepend_env path r"C:\Eigenes\compiler\vcc2005\Common7\IDE;"
|
@prepend_env path r"C:\Programme\Microsoft Visual Studio 9.0\Common7\IDE;"
|
||||||
@prepend_env INCLUDE r"C:\Eigenes\compiler\vcc2005\VC\include;C:\Eigenes\compiler\vcc2005\VC\ATLMFC\INCLUDE;"
|
@prepend_env INCLUDE r"C:\Programme\Microsoft Visual Studio 9.0\VC\include;C:\Programme\Microsoft Visual Studio 9.0\VC\ATLMFC\INCLUDE;C:\Programme\Microsoft SDKs\Windows\v6.0A\Include;"
|
||||||
@prepend_env LIB r"C:\Eigenes\compiler\vcc2005\VC\lib;C:\Eigenes\compiler\vcc2005\SDK\v2.0\Lib;"
|
@prepend_env LIB r"C:\Programme\Microsoft Visual Studio 9.0\VC\lib;C:\Programme\Microsoft Visual Studio 9.0\SDK\v2.0\Lib;C:\Programme\Microsoft SDKs\Windows\v6.0A\Lib;"
|
||||||
|
passl: r"/F33554432" # set the stack size to 8 MB
|
||||||
@end
|
@end
|
||||||
@if windows:
|
@if windows:
|
||||||
vcc.path = r"C:\Eigenes\compiler\vcc2005\VC\bin"
|
vcc.path = r"C:\Programme\Microsoft Visual Studio 9.0\VC\bin"
|
||||||
@end
|
@end
|
||||||
vcc.options.debug = "/GZ /ZI"
|
vcc.options.debug = "/RTC1 /ZI"
|
||||||
vcc.options.always = "/nologo"
|
vcc.options.always = "/nologo"
|
||||||
vcc.options.speed = "/Ogityb2 /G7 /arch:SSE2"
|
vcc.options.speed = "/Ogityb2 /G7 /arch:SSE2"
|
||||||
vcc.options.size = "/O1 /G7"
|
vcc.options.size = "/O1 /G7"
|
||||||
|
|
@ -113,10 +123,11 @@ lcc.options.size = "-O -p6"
|
||||||
|
|
||||||
# Configuration for the Tiny C Compiler:
|
# Configuration for the Tiny C Compiler:
|
||||||
@if windows:
|
@if windows:
|
||||||
tcc.path = r"C:\eigenes\compiler\tcc\bin"
|
tcc.path = r"C:\Eigenes\compiler\tcc-0.9.23\tcc"
|
||||||
|
tcc.options.always = r"-IC:\Eigenes\compiler\tcc-0.9.23\include " &
|
||||||
|
r"-IC:\Eigenes\compiler\tcc-0.9.23\include\winapi"
|
||||||
@end
|
@end
|
||||||
tcc.options.debug = "-b"
|
tcc.options.debug = ""
|
||||||
tcc.options.always = ""
|
|
||||||
tcc.options.speed = ""
|
tcc.options.speed = ""
|
||||||
tcc.options.size = ""
|
tcc.options.size = ""
|
||||||
|
|
||||||
|
|
@ -137,4 +148,9 @@ icc.options.always = "-w"
|
||||||
icc.options.speed = "-O3 -ffast-math"
|
icc.options.speed = "-O3 -ffast-math"
|
||||||
icc.options.size = "-Os -ffast-math"
|
icc.options.size = "-Os -ffast-math"
|
||||||
|
|
||||||
@write "used default config file"
|
@write "used special config file"
|
||||||
|
|
||||||
|
@if ecmascript:
|
||||||
|
@write "Target is ECMAScript! No unsafe features are allowed!"
|
||||||
|
@end
|
||||||
|
|
||||||
|
|
|
||||||
49
data/ast.yml
49
data/ast.yml
|
|
@ -9,7 +9,7 @@
|
||||||
|
|
||||||
{
|
{
|
||||||
'SymFlag': [ # already 32 flags!
|
'SymFlag': [ # already 32 flags!
|
||||||
'sfGeneric', # whether an operator, proc or type is generic
|
'sfTypeCheck', # wether macro parameters should be type checked
|
||||||
'sfForward', # symbol is forward directed
|
'sfForward', # symbol is forward directed
|
||||||
'sfImportc', # symbol is external; imported
|
'sfImportc', # symbol is external; imported
|
||||||
'sfExportc', # symbol is exported (under a specified name)
|
'sfExportc', # symbol is exported (under a specified name)
|
||||||
|
|
@ -26,7 +26,7 @@
|
||||||
'sfMainModule', # module is the main module
|
'sfMainModule', # module is the main module
|
||||||
'sfSystemModule', # module is the system module
|
'sfSystemModule', # module is the system module
|
||||||
'sfNoReturn', # proc never returns (an exit proc)
|
'sfNoReturn', # proc never returns (an exit proc)
|
||||||
'sfReturnsNew', # proc returns new allocated thing (allows optimizations)
|
'sfAddrTaken', # the variable's address is taken (ex- or implicitely)
|
||||||
'sfInInterface', # symbol is in interface section declared
|
'sfInInterface', # symbol is in interface section declared
|
||||||
'sfNoStatic', # symbol is used within an iterator (needed for codegen)
|
'sfNoStatic', # symbol is used within an iterator (needed for codegen)
|
||||||
# so it cannot be 'static' in the C code
|
# so it cannot be 'static' in the C code
|
||||||
|
|
@ -56,19 +56,19 @@
|
||||||
# is used to speed up semantic checking a bit
|
# is used to speed up semantic checking a bit
|
||||||
'tfEnumHasWholes', # enum cannot be mapped into a range
|
'tfEnumHasWholes', # enum cannot be mapped into a range
|
||||||
'tfVarargs', # procedure has C styled varargs
|
'tfVarargs', # procedure has C styled varargs
|
||||||
'tfAssignable' # can the type be assigned to?
|
'tfFinal' # is the object final?
|
||||||
],
|
],
|
||||||
|
|
||||||
'TypeKind': [ # order is important!
|
'TypeKind': [ # order is important!
|
||||||
# Don't forget to change hti.nim if you make a change here
|
# Don't forget to change hti.nim if you make a change here
|
||||||
'tyNone', 'tyBool', 'tyChar',
|
'tyNone', 'tyBool', 'tyChar',
|
||||||
'tyEmptySet', 'tyArrayConstr', 'tyNil', 'tyRecordConstr',
|
'tyEmptySet', 'tyArrayConstr', 'tyNil',
|
||||||
'tyGeneric',
|
'tyGeneric',
|
||||||
'tyGenericInst', # instantiated generic type
|
'tyGenericInst', # instantiated generic type
|
||||||
'tyGenericParam',
|
'tyGenericParam',
|
||||||
'tyEnum', 'tyAnyEnum',
|
'tyEnum',
|
||||||
|
'tyAnyEnum',
|
||||||
'tyArray',
|
'tyArray',
|
||||||
'tyRecord',
|
|
||||||
'tyObject',
|
'tyObject',
|
||||||
'tyTuple',
|
'tyTuple',
|
||||||
'tySet',
|
'tySet',
|
||||||
|
|
@ -84,6 +84,14 @@
|
||||||
'tyFloat', 'tyFloat32', 'tyFloat64', 'tyFloat128'
|
'tyFloat', 'tyFloat32', 'tyFloat64', 'tyFloat128'
|
||||||
],
|
],
|
||||||
|
|
||||||
|
'NodeFlag': [ # keep this number under 16 for performance reasons!
|
||||||
|
'nfNone',
|
||||||
|
'nfBase2', # nfBase10 is default, so not needed
|
||||||
|
'nfBase8',
|
||||||
|
'nfBase16',
|
||||||
|
'nfAllConst' # used to mark complex expressions constant
|
||||||
|
],
|
||||||
|
|
||||||
'NodeKind': [ # these are pure nodes
|
'NodeKind': [ # these are pure nodes
|
||||||
# order is extremely important, because ranges are used to check whether
|
# order is extremely important, because ranges are used to check whether
|
||||||
# a node belongs to a certain class
|
# a node belongs to a certain class
|
||||||
|
|
@ -97,7 +105,6 @@
|
||||||
'nkType', # node is used for its typ field
|
'nkType', # node is used for its typ field
|
||||||
|
|
||||||
'nkCharLit', # a character literal ''
|
'nkCharLit', # a character literal ''
|
||||||
'nkRCharLit', # a raw character literal r''
|
|
||||||
|
|
||||||
'nkIntLit', # an integer literal
|
'nkIntLit', # an integer literal
|
||||||
'nkInt8Lit',
|
'nkInt8Lit',
|
||||||
|
|
@ -110,6 +117,8 @@
|
||||||
'nkStrLit', # a string literal ""
|
'nkStrLit', # a string literal ""
|
||||||
'nkRStrLit', # a raw string literal r""
|
'nkRStrLit', # a raw string literal r""
|
||||||
'nkTripleStrLit', # a triple string literal """
|
'nkTripleStrLit', # a triple string literal """
|
||||||
|
'nkMetaNode', # difficult to explan; represents itself
|
||||||
|
# (used for macros)
|
||||||
'nkNilLit', # the nil literal
|
'nkNilLit', # the nil literal
|
||||||
# end of atoms
|
# end of atoms
|
||||||
'nkDotCall', # used to temporarily flag a nkCall node; this is used
|
'nkDotCall', # used to temporarily flag a nkCall node; this is used
|
||||||
|
|
@ -126,7 +135,7 @@
|
||||||
'nkInfix', # a call like (a + b)
|
'nkInfix', # a call like (a + b)
|
||||||
'nkPrefix', # a call like !a
|
'nkPrefix', # a call like !a
|
||||||
'nkPostfix', # something like a! (also used for visibility)
|
'nkPostfix', # something like a! (also used for visibility)
|
||||||
'nkPar', # syntactic ()
|
'nkPar', # syntactic (); may be a tuple constructor
|
||||||
'nkCurly', # syntactic {}
|
'nkCurly', # syntactic {}
|
||||||
'nkBracket', # syntactic []
|
'nkBracket', # syntactic []
|
||||||
'nkBracketExpr', # an expression like a[i..j, k]
|
'nkBracketExpr', # an expression like a[i..j, k]
|
||||||
|
|
@ -142,14 +151,7 @@
|
||||||
'nkAccQuoted', # `a` as a node
|
'nkAccQuoted', # `a` as a node
|
||||||
'nkHeaderQuoted', # `a(x: int)` as a node
|
'nkHeaderQuoted', # `a(x: int)` as a node
|
||||||
|
|
||||||
'nkSetConstr', # a set constructor {}
|
|
||||||
'nkConstSetConstr', # a set constructor with only constant expressions
|
|
||||||
'nkArrayConstr', # an array constructor []
|
|
||||||
'nkConstArrayConstr', # an array constructor with only constant expressions
|
|
||||||
'nkRecordConstr', # a record constructor []
|
|
||||||
'nkConstRecordConstr', # a record constructor with only constant expressions
|
|
||||||
'nkTableConstr', # a table constructor {expr: expr}
|
'nkTableConstr', # a table constructor {expr: expr}
|
||||||
'nkConstTableConstr', # a table constructor with only constant expressions
|
|
||||||
'nkQualified', # describes a.b for qualified identifiers
|
'nkQualified', # describes a.b for qualified identifiers
|
||||||
'nkHiddenStdConv', # an implicit standard type conversion
|
'nkHiddenStdConv', # an implicit standard type conversion
|
||||||
'nkHiddenSubConv', # an implicit type conversion from a subtype
|
'nkHiddenSubConv', # an implicit type conversion from a subtype
|
||||||
|
|
@ -158,6 +160,16 @@
|
||||||
'nkConv', # a type conversion
|
'nkConv', # a type conversion
|
||||||
'nkCast', # a type cast
|
'nkCast', # a type cast
|
||||||
'nkAddr', # a addr expression
|
'nkAddr', # a addr expression
|
||||||
|
'nkHiddenAddr', # implicit address operator
|
||||||
|
'nkHiddenDeref', # implicit ^ operator
|
||||||
|
'nkObjDownConv', # down conversion between object types
|
||||||
|
'nkObjUpConv', # up conversion between object types
|
||||||
|
'nkChckRangeF', # range check for floats
|
||||||
|
'nkChckRange64', # range check for 64 bit ints
|
||||||
|
'nkChckRange', # range check for ints
|
||||||
|
'nkStringToCString', # string to cstring
|
||||||
|
'nkCStringToString', # cstring to string
|
||||||
|
'nkPassAsOpenArray', # thing is passed as an open array
|
||||||
# end of expressions
|
# end of expressions
|
||||||
|
|
||||||
'nkAsgn', # a = b
|
'nkAsgn', # a = b
|
||||||
|
|
@ -198,8 +210,6 @@
|
||||||
'nkBreakStmt', # a break statement
|
'nkBreakStmt', # a break statement
|
||||||
'nkContinueStmt', # a continue statement
|
'nkContinueStmt', # a continue statement
|
||||||
'nkBlockStmt', # a block statement
|
'nkBlockStmt', # a block statement
|
||||||
'nkGotoStmt', # used by the transformation pass; first son is a sym
|
|
||||||
# node containing a label
|
|
||||||
'nkDiscardStmt', # a discard statement
|
'nkDiscardStmt', # a discard statement
|
||||||
'nkStmtList', # a list of statements
|
'nkStmtList', # a list of statements
|
||||||
'nkImportStmt', # an import statement
|
'nkImportStmt', # an import statement
|
||||||
|
|
@ -218,8 +228,8 @@
|
||||||
|
|
||||||
# types as syntactic trees:
|
# types as syntactic trees:
|
||||||
'nkTypeOfExpr',
|
'nkTypeOfExpr',
|
||||||
'nkRecordTy',
|
|
||||||
'nkObjectTy',
|
'nkObjectTy',
|
||||||
|
'nkTupleTy',
|
||||||
'nkRecList', # list of record/object parts
|
'nkRecList', # list of record/object parts
|
||||||
'nkRecCase', # case section of record/object
|
'nkRecCase', # case section of record/object
|
||||||
'nkRecWhen', # when section of record/object
|
'nkRecWhen', # when section of record/object
|
||||||
|
|
@ -228,7 +238,8 @@
|
||||||
'nkVarTy',
|
'nkVarTy',
|
||||||
'nkProcTy',
|
'nkProcTy',
|
||||||
'nkEnumTy',
|
'nkEnumTy',
|
||||||
'nkEnumFieldDef' # `ident = expr` in an enumeration
|
'nkEnumFieldDef', # `ident = expr` in an enumeration
|
||||||
|
'nkReturnToken', # token used for interpretation
|
||||||
],
|
],
|
||||||
|
|
||||||
'SymKind': [
|
'SymKind': [
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ Command::
|
||||||
compile compile project with default code generator (C)
|
compile compile project with default code generator (C)
|
||||||
compile_to_c compile project with C code generator
|
compile_to_c compile project with C code generator
|
||||||
compile_to_cpp compile project with C++ code generator
|
compile_to_cpp compile project with C++ code generator
|
||||||
|
compile_to_ecmascript compile project to ECMAScript code (experimental)
|
||||||
doc generate the documentation for inputfile;
|
doc generate the documentation for inputfile;
|
||||||
with --run switch opens it with $BROWSER
|
with --run switch opens it with $BROWSER
|
||||||
Arguments:
|
Arguments:
|
||||||
|
|
@ -18,6 +19,8 @@ Options:
|
||||||
--line_trace:on|off code generation for line trace ON|OFF
|
--line_trace:on|off code generation for line trace ON|OFF
|
||||||
--debugger:on|off turn Embedded Nimrod Debugger ON|OFF
|
--debugger:on|off turn Embedded Nimrod Debugger ON|OFF
|
||||||
-x, --checks:on|off code generation for all runtime checks ON|OFF
|
-x, --checks:on|off code generation for all runtime checks ON|OFF
|
||||||
|
--obj_checks:on|off code generation for obj conversion checks ON|OFF
|
||||||
|
--field_checks:on|off code generation for case record fields ON|OFF
|
||||||
--range_checks:on|off code generation for range checks ON|OFF
|
--range_checks:on|off code generation for range checks ON|OFF
|
||||||
--bound_checks:on|off code generation for bound checks ON|OFF
|
--bound_checks:on|off code generation for bound checks ON|OFF
|
||||||
--overflow_checks:on|off code generation for over-/underflow checks ON|OFF
|
--overflow_checks:on|off code generation for over-/underflow checks ON|OFF
|
||||||
|
|
|
||||||
|
|
@ -10,9 +10,9 @@ macro method mod
|
||||||
nil not notin
|
nil not notin
|
||||||
object of or out
|
object of or out
|
||||||
proc ptr
|
proc ptr
|
||||||
raise record ref return
|
raise ref return
|
||||||
shl shr
|
shl shr
|
||||||
template try type
|
template try tuple type
|
||||||
var
|
var
|
||||||
when where while with without
|
when where while with without
|
||||||
xor
|
xor
|
||||||
|
|
|
||||||
|
|
@ -113,8 +113,13 @@
|
||||||
'UnaryPlusF64',
|
'UnaryPlusF64',
|
||||||
'UnaryMinusF64',
|
'UnaryMinusF64',
|
||||||
'AbsF64',
|
'AbsF64',
|
||||||
'Ze',
|
'Ze8ToI',
|
||||||
'Ze64',
|
'Ze8ToI64',
|
||||||
|
'Ze16ToI',
|
||||||
|
'Ze16ToI64',
|
||||||
|
'Ze32ToI64',
|
||||||
|
'ZeIToI64',
|
||||||
|
|
||||||
'ToU8',
|
'ToU8',
|
||||||
'ToU16',
|
'ToU16',
|
||||||
'ToU32',
|
'ToU32',
|
||||||
|
|
@ -123,6 +128,14 @@
|
||||||
'ToInt',
|
'ToInt',
|
||||||
'ToBiggestInt',
|
'ToBiggestInt',
|
||||||
|
|
||||||
|
'CharToStr',
|
||||||
|
'BoolToStr',
|
||||||
|
'IntToStr', # $ for ints
|
||||||
|
'Int64ToStr',
|
||||||
|
'FloatToStr',
|
||||||
|
'CStrToStr',
|
||||||
|
'StrToStr',
|
||||||
|
|
||||||
# special ones:
|
# special ones:
|
||||||
'And',
|
'And',
|
||||||
'Or',
|
'Or',
|
||||||
|
|
@ -156,12 +169,12 @@
|
||||||
'SetLengthSeq',
|
'SetLengthSeq',
|
||||||
'Assert',
|
'Assert',
|
||||||
'Swap',
|
'Swap',
|
||||||
|
'IsNil',
|
||||||
|
|
||||||
# magic type constructors:
|
# magic type constructors:
|
||||||
'Array',
|
'Array',
|
||||||
'OpenArray',
|
'OpenArray',
|
||||||
'Range',
|
'Range',
|
||||||
'Tuple',
|
|
||||||
'Set',
|
'Set',
|
||||||
'Seq',
|
'Seq',
|
||||||
|
|
||||||
|
|
@ -172,5 +185,38 @@
|
||||||
'NimrodMajor',
|
'NimrodMajor',
|
||||||
'NimrodMinor',
|
'NimrodMinor',
|
||||||
'NimrodPatch',
|
'NimrodPatch',
|
||||||
'CpuEndian'
|
'CpuEndian',
|
||||||
|
'NaN',
|
||||||
|
'Inf',
|
||||||
|
'NegInf',
|
||||||
|
|
||||||
|
# magics for modifying the AST (macro support)
|
||||||
|
'NLen',
|
||||||
|
'NChild',
|
||||||
|
'NSetChild',
|
||||||
|
'NAdd',
|
||||||
|
'NAddMultiple',
|
||||||
|
'NDel',
|
||||||
|
'NKind',
|
||||||
|
'NIntVal',
|
||||||
|
'NFloatVal',
|
||||||
|
'NSymbol',
|
||||||
|
'NIdent',
|
||||||
|
'NGetType',
|
||||||
|
'NStrVal',
|
||||||
|
'NSetIntVal',
|
||||||
|
'NSetFloatVal',
|
||||||
|
'NSetSymbol',
|
||||||
|
'NSetIdent',
|
||||||
|
'NSetType',
|
||||||
|
'NSetStrVal',
|
||||||
|
'NNewNimNode',
|
||||||
|
'NCopyNimNode',
|
||||||
|
'NCopyNimTree',
|
||||||
|
'StrToIdent',
|
||||||
|
'IdentToStr',
|
||||||
|
'EqIdent',
|
||||||
|
'NHint',
|
||||||
|
'NWarning',
|
||||||
|
'NError'
|
||||||
]
|
]
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@
|
||||||
{'errInvalidToken': 'invalid token: $1'},
|
{'errInvalidToken': 'invalid token: $1'},
|
||||||
{'errLineTooLong': 'line too long'},
|
{'errLineTooLong': 'line too long'},
|
||||||
{'errInvalidNumber': '$1 is not a valid number'},
|
{'errInvalidNumber': '$1 is not a valid number'},
|
||||||
{'errNumberOutOfRange': '$1 is too large or too small'},
|
{'errNumberOutOfRange': 'number $1 out of valid range'},
|
||||||
{'errNnotAllowedInCharacter': '\\n not allowed in character literal'},
|
{'errNnotAllowedInCharacter': '\\n not allowed in character literal'},
|
||||||
{'errClosingBracketExpected': "closing ']' expected, but end of file reached"},
|
{'errClosingBracketExpected': "closing ']' expected, but end of file reached"},
|
||||||
{'errMissingFinalQuote': "missing final '"},
|
{'errMissingFinalQuote': "missing final '"},
|
||||||
|
|
@ -32,10 +32,6 @@
|
||||||
{'errTokenExpected': "'$1' expected"},
|
{'errTokenExpected': "'$1' expected"},
|
||||||
{'errStringAfterIncludeExpected': "string after 'include' expected"},
|
{'errStringAfterIncludeExpected': "string after 'include' expected"},
|
||||||
{'errRecursiveInclude': "recursive include file: '$1'"},
|
{'errRecursiveInclude': "recursive include file: '$1'"},
|
||||||
{'errAtIfExpected': "'@if' expected"},
|
|
||||||
{'errAtIfExpectedBeforeElse': "'@if' expected before '@else'"},
|
|
||||||
{'errAtIfExpectedBeforeElif': "'@if' expected before '@elif'"},
|
|
||||||
{'errAtEndExpected': "'@end' expected"},
|
|
||||||
{'errOnOrOffExpected': "'on' or 'off' expected"},
|
{'errOnOrOffExpected': "'on' or 'off' expected"},
|
||||||
{'errNoneSpeedOrSizeExpected': "'none', 'speed' or 'size' expected"},
|
{'errNoneSpeedOrSizeExpected': "'none', 'speed' or 'size' expected"},
|
||||||
{'errInvalidPragma': 'invalid pragma'},
|
{'errInvalidPragma': 'invalid pragma'},
|
||||||
|
|
@ -157,13 +153,13 @@
|
||||||
{'errSizeTooBig': "computing the type's size produced an overflow"},
|
{'errSizeTooBig': "computing the type's size produced an overflow"},
|
||||||
{'errSetTooBig': 'set is too large'},
|
{'errSetTooBig': 'set is too large'},
|
||||||
{'errBaseTypeMustBeOrdinal': 'base type of a set must be an ordinal'},
|
{'errBaseTypeMustBeOrdinal': 'base type of a set must be an ordinal'},
|
||||||
{'errInheritanceOnlyWithObjects': 'inheritance only works with an object'},
|
{'errInheritanceOnlyWithNonFinalObjects': 'inheritance only works non-final objects'},
|
||||||
{'errInheritanceOnlyWithEnums': 'inheritance only works with an enum'},
|
{'errInheritanceOnlyWithEnums': 'inheritance only works with an enum'},
|
||||||
{'errIllegalRecursionInTypeX': "illegal recursion in type '$1'"},
|
{'errIllegalRecursionInTypeX': "illegal recursion in type '$1'"},
|
||||||
{'errCannotInstantiateX': "cannot instantiate: '$1'"},
|
{'errCannotInstantiateX': "cannot instantiate: '$1'"},
|
||||||
{'errExprHasNoAddress': 'expression has no address'},
|
{'errExprHasNoAddress': "expression has no address"},
|
||||||
{'errVarForOutParamNeeded':
|
{'errVarForOutParamNeeded':
|
||||||
'to an out parameter a variable needs to be passed'},
|
"for a 'var' type a variable needs to be passed"},
|
||||||
{'errPureTypeMismatch': 'type mismatch'},
|
{'errPureTypeMismatch': 'type mismatch'},
|
||||||
{'errTypeMismatch': 'type mismatch: got ('},
|
{'errTypeMismatch': 'type mismatch: got ('},
|
||||||
{'errButExpected': 'but expected one of: '},
|
{'errButExpected': 'but expected one of: '},
|
||||||
|
|
@ -243,6 +239,20 @@
|
||||||
{'errWhitespaceExpected': "whitespace expected, got '$1'"},
|
{'errWhitespaceExpected': "whitespace expected, got '$1'"},
|
||||||
{'errXisNoValidIndexFile': "'$1' is no valid index file"},
|
{'errXisNoValidIndexFile': "'$1' is no valid index file"},
|
||||||
{'errCannotRenderX': "cannot render reStructuredText element '$1'"},
|
{'errCannotRenderX': "cannot render reStructuredText element '$1'"},
|
||||||
|
{'errVarVarTypeNotAllowed': "type 'var var' is not allowed"},
|
||||||
|
{'errIsExpectsTwoArguments': "'is' expects two arguments"},
|
||||||
|
{'errIsExpectsObjectTypes': "'is' expects object types"},
|
||||||
|
{'errXcanNeverBeOfThisSubtype': "'$1' can never be of this subtype"},
|
||||||
|
{'errTooManyIterations': "interpretation requires too many iterations"},
|
||||||
|
{'errCannotInterpretNodeX': "cannot interpret node kind '$1'"},
|
||||||
|
{'errFieldXNotFound': "field '$1' cannot be found"},
|
||||||
|
{'errInvalidConversionFromTypeX': "invalid conversion from type '$1'"},
|
||||||
|
{'errAssertionFailed': "assertion failed"},
|
||||||
|
{'errCannotGenerateCodeForX': "cannot generate code for '$1'"},
|
||||||
|
{'errXNeedsReturnType': "converter needs return type"},
|
||||||
|
{'errXRequiresOneArgument': "converter requires one parameter"},
|
||||||
|
{'errUnhandledExceptionX': "unhandled exception: $1"},
|
||||||
|
{'errCyclicTree': "macro returned a cyclic abstract syntax tree"},
|
||||||
|
|
||||||
# user error message:
|
# user error message:
|
||||||
{'errUser': '$1'},
|
{'errUser': '$1'},
|
||||||
|
|
@ -276,6 +286,8 @@
|
||||||
{'hintMo2FileInvalid': "mo2 file '$1' is invalid"},
|
{'hintMo2FileInvalid': "mo2 file '$1' is invalid"},
|
||||||
{'hintModuleHasChanged': "module '$1' has been changed"},
|
{'hintModuleHasChanged': "module '$1' has been changed"},
|
||||||
{'hintCannotOpenMo2File': "mo2 file '$1' does not exist"},
|
{'hintCannotOpenMo2File': "mo2 file '$1' does not exist"},
|
||||||
|
{'hintQuitCalled': "quit() called"},
|
||||||
|
{'hintProcessing': "processing"},
|
||||||
|
|
||||||
# user hint message:
|
# user hint message:
|
||||||
{'hintUser': '$1'}
|
{'hintUser': '$1'}
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,9 @@
|
||||||
|
|
||||||
The documentation consists of several documents:
|
The documentation consists of several documents:
|
||||||
|
|
||||||
|
- | `First steps after installation <steps.html>`_
|
||||||
|
| Read this after installation for a quick introduction.
|
||||||
|
|
||||||
- | `Nimrod manual <manual.html>`_
|
- | `Nimrod manual <manual.html>`_
|
||||||
| Read this to get to know the Nimrod programming system.
|
| Read this to get to know the Nimrod programming system.
|
||||||
|
|
||||||
|
|
@ -23,4 +26,3 @@ The documentation consists of several documents:
|
||||||
- | `Index <theindex.html>`_
|
- | `Index <theindex.html>`_
|
||||||
| The generated index. Often the quickest way to find the piece of
|
| The generated index. Often the quickest way to find the piece of
|
||||||
information you need.
|
information you need.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -78,6 +78,7 @@ typeDescK ::= VAR typeDesc
|
||||||
| REF typeDesc
|
| REF typeDesc
|
||||||
| PTR typeDesc
|
| PTR typeDesc
|
||||||
| TYPE expr
|
| TYPE expr
|
||||||
|
| TUPLE tupleDesc
|
||||||
| PROC paramList [pragma]
|
| PROC paramList [pragma]
|
||||||
|
|
||||||
typeDesc ::= typeDescK | primary
|
typeDesc ::= typeDescK | primary
|
||||||
|
|
@ -157,23 +158,23 @@ colonAndEquals ::= [COLON typeDesc] EQUALS expr
|
||||||
constDecl ::= symbol ["*"] [pragma] colonAndEquals [COMMENT | IND COMMENT]
|
constDecl ::= symbol ["*"] [pragma] colonAndEquals [COMMENT | IND COMMENT]
|
||||||
| COMMENT
|
| COMMENT
|
||||||
constSection ::= CONST indPush constDecl (SAD constDecl)* DED
|
constSection ::= CONST indPush constDecl (SAD constDecl)* DED
|
||||||
typeDef ::= typeDesc | recordDef | objectDef | enumDef
|
typeDef ::= typeDesc | objectDef | enumDef
|
||||||
|
|
||||||
recordIdentPart ::=
|
objectIdentPart ::=
|
||||||
(symbol ["*" | "-"] [pragma] optComma)+ COLON typeDesc [COMMENT | IND COMMENT]
|
(symbol ["*" | "-"] [pragma] optComma)+ COLON typeDesc [COMMENT | IND COMMENT]
|
||||||
|
|
||||||
recordWhen ::= WHEN expr COLON [COMMENT] recordPart
|
objectWhen ::= WHEN expr COLON [COMMENT] objectPart
|
||||||
(ELIF expr COLON [COMMENT] recordPart)*
|
(ELIF expr COLON [COMMENT] objectPart)*
|
||||||
[ELSE COLON [COMMENT] recordPart]
|
[ELSE COLON [COMMENT] objectPart]
|
||||||
recordCase ::= CASE expr COLON typeDesc [COMMENT]
|
objectCase ::= CASE expr COLON typeDesc [COMMENT]
|
||||||
(OF sliceList COLON [COMMENT] recordPart)*
|
(OF sliceList COLON [COMMENT] objectPart)*
|
||||||
[ELSE COLON [COMMENT] recordPart]
|
[ELSE COLON [COMMENT] objectPart]
|
||||||
|
|
||||||
recordPart ::= recordWhen | recordCase | recordIdentPart
|
objectPart ::= objectWhen | objectCase | objectIdentPart
|
||||||
| indPush recordPart (SAD recordPart)* DED
|
| indPush objectPart (SAD objectPart)* DED
|
||||||
recordDef ::= RECORD [pragma] recordPart
|
tupleDesc ::= BRACKET_LE optInd ((symbol optComma)+ COLON typeDesc optComma)* BRACKET_RI
|
||||||
|
|
||||||
objectDef ::= OBJECT [pragma] [OF typeDesc] recordPart
|
objectDef ::= OBJECT [pragma] [OF typeDesc] objectPart
|
||||||
enumDef ::= ENUM [OF typeDesc] (symbol [EQUALS expr] optComma [COMMENT | IND COMMENT])+
|
enumDef ::= ENUM [OF typeDesc] (symbol [EQUALS expr] optComma [COMMENT | IND COMMENT])+
|
||||||
|
|
||||||
typeDecl ::= COMMENT
|
typeDecl ::= COMMENT
|
||||||
|
|
|
||||||
97
doc/lib.txt
97
doc/lib.txt
|
|
@ -13,36 +13,119 @@ Advanced libraries are in the ``lib/base`` directory.
|
||||||
Basic libraries
|
Basic libraries
|
||||||
===============
|
===============
|
||||||
|
|
||||||
* `System <system.html>`_
|
* `system <system.html>`_
|
||||||
Basic procs and operators that every program needs. It also provides IO
|
Basic procs and operators that every program needs. It also provides IO
|
||||||
facilities for reading and writing text and binary files. It is imported
|
facilities for reading and writing text and binary files. It is imported
|
||||||
implicitly by the compiler. Do not import it directly. It relies on compiler
|
implicitly by the compiler. Do not import it directly. It relies on compiler
|
||||||
magic to work.
|
magic to work.
|
||||||
|
|
||||||
* `Strutils <strutils.html>`_
|
* `strutils <strutils.html>`_
|
||||||
This module contains common string handling operations like converting a
|
This module contains common string handling operations like converting a
|
||||||
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.
|
||||||
|
|
||||||
* `OS <os.html>`_
|
* `os <os.html>`_
|
||||||
Basic operating system facilities like retrieving environment variables,
|
Basic operating system facilities like retrieving environment variables,
|
||||||
reading command line arguments, working with directories, running shell
|
reading command line arguments, working with directories, running shell
|
||||||
commands, etc. This module is -- like any other basic library --
|
commands, etc. This module is -- like any other basic library --
|
||||||
platform independant.
|
platform independant.
|
||||||
|
|
||||||
* `Math <math.html>`_
|
* `math <math.html>`_
|
||||||
Mathematical operations like cosine, square root.
|
Mathematical operations like cosine, square root.
|
||||||
|
|
||||||
* `Complex <complex.html>`_
|
* `complex <complex.html>`_
|
||||||
This module implements complex numbers and their mathematical operations.
|
This module implements complex numbers and their mathematical operations.
|
||||||
|
|
||||||
* `Times <times.html>`_
|
* `times <times.html>`_
|
||||||
The ``times`` module contains basic support for working with time.
|
The ``times`` module contains basic support for working with time.
|
||||||
|
|
||||||
|
* `parseopt <parseopt.html>`_
|
||||||
|
The ``parseopt`` module implements a command line option parser. This
|
||||||
|
supports long and short command options with optional values and command line
|
||||||
|
arguments.
|
||||||
|
|
||||||
|
* `parsecfg <parsecfg.html>`_
|
||||||
|
The ``parsecfg`` module implements a high performance configuration file
|
||||||
|
parser. The configuration file's syntax is similar to the Windows ``.ini``
|
||||||
|
format, but much more powerful, as it is not a line based parser. String
|
||||||
|
literals, raw string literals and triple quote string literals are supported
|
||||||
|
as in the Nimrod programming language.
|
||||||
|
|
||||||
|
* `strtabs <strtabs.html>`_
|
||||||
|
The ``strtabs`` module implements an efficient hash table that is a mapping
|
||||||
|
from strings to strings. Supports a case-sensitive, case-insensitive and
|
||||||
|
style-insensitive mode. An efficient string substitution operator ``%``
|
||||||
|
for the string table is also provided.
|
||||||
|
|
||||||
|
* `hashes <hashes.html>`_
|
||||||
|
This module implements efficient computations of hash values for diverse
|
||||||
|
Nimrod types.
|
||||||
|
|
||||||
|
* `lexbase <lexbase.html>`_
|
||||||
|
This is a low leve module that implements an extremely efficent buffering
|
||||||
|
scheme for lexers and parsers. This is used by the ``parsecfg`` module.
|
||||||
|
|
||||||
|
|
||||||
Advanced libaries
|
Advanced libaries
|
||||||
=================
|
=================
|
||||||
|
|
||||||
* `Regexprs <regexprs.html>`_
|
* `regexprs <regexprs.html>`_
|
||||||
This module contains procedures and operators for handling regular
|
This module contains procedures and operators for handling regular
|
||||||
expressions.
|
expressions.
|
||||||
|
|
||||||
|
* `dialogs <dialogs.html>`_
|
||||||
|
This module implements portable dialogs for Nimrod; the implementation
|
||||||
|
builds on the GTK interface. On Windows, native dialogs are shown if
|
||||||
|
appropriate.
|
||||||
|
|
||||||
|
|
||||||
|
Wrappers
|
||||||
|
========
|
||||||
|
|
||||||
|
Note that the generated HTML for some of these wrappers is so huge, that it is
|
||||||
|
not contained in the distribution. You can then find them on the website.
|
||||||
|
|
||||||
|
* `posix <posix.html>`_
|
||||||
|
Contains a wrapper for the POSIX standard.
|
||||||
|
* `windows <windows.html>`_
|
||||||
|
Contains a wrapper for the Win32 API.
|
||||||
|
* `shellapi <shellapi.html>`_
|
||||||
|
Contains a wrapper for the ``shellapi.h`` header.
|
||||||
|
* `shfolder <shfolder.html>`_
|
||||||
|
Contains a wrapper for the ``shfolder.h`` header.
|
||||||
|
* `mmsystem <mmsystem.html>`_
|
||||||
|
Contains a wrapper for the ``mmsystem.h`` header.
|
||||||
|
* `ole2 <ole2.html>`_
|
||||||
|
Contains GUIDs for OLE2 automation support.
|
||||||
|
* `nb30 <nb30.html>`_
|
||||||
|
This module contains the definitions for portable NetBIOS 3.0 support.
|
||||||
|
* `cairo <cairo.html>`_
|
||||||
|
Wrapper for the cairo library.
|
||||||
|
* `cairoft <cairoft.html>`_
|
||||||
|
Wrapper for the cairoft library.
|
||||||
|
* `cairowin32 <cairowin32.html>`_
|
||||||
|
Wrapper for the cairowin32 library.
|
||||||
|
* `cairoxlib <cairoxlib.html>`_
|
||||||
|
Wrapper for the cairoxlib library.
|
||||||
|
* `atk <atk.html>`_
|
||||||
|
Wrapper for the atk library.
|
||||||
|
* `gdk2 <gdk2.html>`_
|
||||||
|
Wrapper for the gdk2 library.
|
||||||
|
* `gdk2pixbuf <gdk2pixbuf.html>`_
|
||||||
|
Wrapper for the gdk2pixbuf library.
|
||||||
|
* `gdkglext <gdkglext.html>`_
|
||||||
|
Wrapper for the gdkglext library.
|
||||||
|
* `glib2 <glib2.html>`_
|
||||||
|
Wrapper for the glib2 library.
|
||||||
|
* `gtk2 <gtk2.html>`_
|
||||||
|
Wrapper for the gtk2 library.
|
||||||
|
* `gtkglext <gtkglext.html>`_
|
||||||
|
Wrapper for the gtkglext library.
|
||||||
|
* `gtkhtml <gtkhtml.html>`_
|
||||||
|
Wrapper for the gtkhtml library.
|
||||||
|
* `libglade2 <libglade2.html>`_
|
||||||
|
Wrapper for the libglade2 library.
|
||||||
|
* `pango <pango.html>`_
|
||||||
|
Wrapper for the pango library.
|
||||||
|
* `pangoutils <pangoutils.html>`_
|
||||||
|
Wrapper for the pangoutils library.
|
||||||
|
|
|
||||||
|
|
@ -593,7 +593,7 @@ Structured types
|
||||||
~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~
|
||||||
A variable of a `structured type`:idx: can hold multiple values at the same
|
A variable of a `structured type`:idx: can hold multiple values at the same
|
||||||
time. Stuctured types can be nested to unlimited levels. Arrays, sequences,
|
time. Stuctured types can be nested to unlimited levels. Arrays, sequences,
|
||||||
records, objects and sets belong to the structured types.
|
tuples, objects and sets belong to the structured types.
|
||||||
|
|
||||||
Array and sequence types
|
Array and sequence types
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
@ -638,42 +638,47 @@ checks can be disabled via pragmas or invoking the compiler with the
|
||||||
``--bound_checks:off`` command line switch.
|
``--bound_checks:off`` command line switch.
|
||||||
|
|
||||||
|
|
||||||
Tuples, record and object types
|
Tuples and object types
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
A variable of a `record`:idx: or `object`:idx: type is a heterogenous storage
|
A variable of a `tuple`:idx: or `object`:idx: type is a heterogenous storage
|
||||||
container.
|
container.
|
||||||
A record or object defines various named *fields* of a type. The assignment
|
A tuple or object defines various named *fields* of a type. A tuple defines an
|
||||||
operator for records and objects always copies the whole record/object. The
|
*order* of the fields additionally. Tuples are meant for heterogenous storage
|
||||||
constructor ``()`` can be used to initialize records/objects. A field may
|
types with no overhead and few abstraction possibilities. The constructor ``()``
|
||||||
be given a default value. Fields with default values do not have to be listed
|
can be used to construct tuples. The order of the fields in the constructor
|
||||||
in a record construction, all other fields have to be listed.
|
must match the order of the tuple's definition. Different tuple-types are
|
||||||
|
*equivalent* if they specify the same fields of the same type in the same
|
||||||
|
order.
|
||||||
|
|
||||||
|
The assignment operator for tuples copies each component.
|
||||||
|
The default assignment operator for objects is not defined. The programmer may
|
||||||
|
provide one, however.
|
||||||
|
|
||||||
.. code-block:: nimrod
|
.. code-block:: nimrod
|
||||||
|
|
||||||
type
|
type
|
||||||
TPerson = record # type representing a person
|
TPerson = tuple[name: string, age: int] # type representing a person
|
||||||
name: string # a person consists of a name
|
# a person consists of a name
|
||||||
age: int = 30 # and an age which default value is 30
|
# and an age
|
||||||
|
|
||||||
var
|
var
|
||||||
person: TPerson
|
person: TPerson
|
||||||
person = (name: "Peter") # person.age is its default value (30)
|
person = (name: "Peter", age: 30)
|
||||||
|
# the same, but less readable:
|
||||||
|
person = ("Peter", 30)
|
||||||
|
|
||||||
The implementation aligns the fields for best access performance. The alignment
|
The implementation aligns the fields for best access performance. The alignment
|
||||||
is done in a way that is compatible the way the C compiler does it.
|
is done in a way that is compatible the way the C compiler does it.
|
||||||
|
|
||||||
The difference between records and objects is that objects allow inheritance.
|
Objects provide many features that tuples do not. Object provide inheritance
|
||||||
Objects have access to their type at runtime, so that the ``is`` operator
|
and information hiding. Objects have access to their type at runtime, so that
|
||||||
can be used to determine the object's type. Assignment from an object to its
|
the ``is`` operator can be used to determine the object's type.
|
||||||
parents' object leads to a static or runtime error (the
|
|
||||||
`EInvalidObjectAssignment`:idx: exception is raised).
|
|
||||||
|
|
||||||
.. code-block:: nimrod
|
.. code-block:: nimrod
|
||||||
|
|
||||||
type
|
type
|
||||||
TPerson = object
|
TPerson = object
|
||||||
name: string
|
name*: string # the * means that `name` is accessible from the outside
|
||||||
age: int
|
age: int # no * means that the field is hidden
|
||||||
|
|
||||||
TStudent = object of TPerson # a student is a person
|
TStudent = object of TPerson # a student is a person
|
||||||
id: int # with an id field
|
id: int # with an id field
|
||||||
|
|
@ -681,10 +686,11 @@ parents' object leads to a static or runtime error (the
|
||||||
var
|
var
|
||||||
student: TStudent
|
student: TStudent
|
||||||
person: TPerson
|
person: TPerson
|
||||||
student = (name: "Peter", age: 89, id: 3)
|
|
||||||
person = (name: "Mary", age: 17)
|
|
||||||
assert(student is TStudent) # is true
|
assert(student is TStudent) # is true
|
||||||
person = student # this is an error; person has no storage for id.
|
|
||||||
|
Object fields that should be visible outside from the defining module, have to
|
||||||
|
marked by ``*``. In contrast to tuples, different object types are
|
||||||
|
never *equivalent*.
|
||||||
|
|
||||||
|
|
||||||
Set type
|
Set type
|
||||||
|
|
@ -743,15 +749,15 @@ The ``^`` operator can be used to derefer a reference, the ``addr`` procedure
|
||||||
returns the address of an item. An address is always an untraced reference.
|
returns the address of an item. An address is always an untraced reference.
|
||||||
Thus the usage of ``addr`` is an *unsafe* feature.
|
Thus the usage of ``addr`` is an *unsafe* feature.
|
||||||
|
|
||||||
The ``.`` (access a record field operator) and ``[]`` (array/string/sequence
|
The ``.`` (access a tuple/object field operator)
|
||||||
index operator) operators perform implicit dereferencing operations for
|
and ``[]`` (array/string/sequence index operator) operators perform implicit
|
||||||
reference types:
|
dereferencing operations for reference types:
|
||||||
|
|
||||||
.. code-block:: nimrod
|
.. code-block:: nimrod
|
||||||
|
|
||||||
type
|
type
|
||||||
PNode = ref TNode
|
PNode = ref TNode
|
||||||
TNode = record
|
TNode = object
|
||||||
le, ri: PNode
|
le, ri: PNode
|
||||||
data: int
|
data: int
|
||||||
|
|
||||||
|
|
@ -938,8 +944,8 @@ ref or pointer type nil
|
||||||
procedural type nil
|
procedural type nil
|
||||||
sequence nil
|
sequence nil
|
||||||
string nil (**not** "")
|
string nil (**not** "")
|
||||||
tuple[A, B, ...] (default(A), default(B), ...)
|
tuple[x: A, y: B, ...] (default(A), default(B), ...)
|
||||||
(analogous for objects and records)
|
(analogous for objects)
|
||||||
array[0..., T] [default(T), ...]
|
array[0..., T] [default(T), ...]
|
||||||
range[T] default(T); this may be out of the valid range
|
range[T] default(T); this may be out of the valid range
|
||||||
T = enum cast[T](0); this may be an invalid value
|
T = enum cast[T](0); this may be an invalid value
|
||||||
|
|
@ -1065,7 +1071,7 @@ exceptions:
|
||||||
|
|
||||||
The ``when`` statement enables conditional compilation techniques. As
|
The ``when`` statement enables conditional compilation techniques. As
|
||||||
a special syntatic extension, the ``when`` construct is also available
|
a special syntatic extension, the ``when`` construct is also available
|
||||||
within ``record`` or ``object`` definitions.
|
within ``object`` definitions.
|
||||||
|
|
||||||
|
|
||||||
Raise statement
|
Raise statement
|
||||||
|
|
@ -1117,7 +1123,7 @@ Example:
|
||||||
echo("sum: " & $(parseInt(a) + parseInt(b)))
|
echo("sum: " & $(parseInt(a) + parseInt(b)))
|
||||||
except EOverflow:
|
except EOverflow:
|
||||||
echo("overflow!")
|
echo("overflow!")
|
||||||
except EValue:
|
except EInvalidValue:
|
||||||
echo("could not convert string to integer")
|
echo("could not convert string to integer")
|
||||||
except EIO:
|
except EIO:
|
||||||
echo("IO error!")
|
echo("IO error!")
|
||||||
|
|
@ -1411,7 +1417,7 @@ Type sections
|
||||||
|
|
||||||
Syntax::
|
Syntax::
|
||||||
|
|
||||||
typeDef ::= typeDesc | recordDef | objectDef | enumDef
|
typeDef ::= typeDesc | objectDef | enumDef
|
||||||
genericParams ::= BRACKET_LE (symbol [EQUALS typeDesc] )* BRACKET_RI
|
genericParams ::= BRACKET_LE (symbol [EQUALS typeDesc] )* BRACKET_RI
|
||||||
|
|
||||||
typeDecl ::= TYPE
|
typeDecl ::= TYPE
|
||||||
|
|
@ -1425,11 +1431,11 @@ Example:
|
||||||
.. code-block:: nimrod
|
.. code-block:: nimrod
|
||||||
type # example demonstrates mutually recursive types
|
type # example demonstrates mutually recursive types
|
||||||
PNode = ref TNode # a traced pointer to a TNode
|
PNode = ref TNode # a traced pointer to a TNode
|
||||||
TNode = record
|
TNode = object
|
||||||
le, ri: PNode # left and right subtrees
|
le, ri: PNode # left and right subtrees
|
||||||
sym: ref TSym # leaves contain a reference to a TSym
|
sym: ref TSym # leaves contain a reference to a TSym
|
||||||
|
|
||||||
TSym = record # a symbol
|
TSym = object # a symbol
|
||||||
name: string # the symbol's name
|
name: string # the symbol's name
|
||||||
line: int # the line the symbol was declared in
|
line: int # the line the symbol was declared in
|
||||||
code: PNode # the symbol's abstract syntax tree
|
code: PNode # the symbol's abstract syntax tree
|
||||||
|
|
@ -1447,7 +1453,7 @@ Example:
|
||||||
|
|
||||||
.. code-block:: nimrod
|
.. code-block:: nimrod
|
||||||
type
|
type
|
||||||
TBinaryTree[T] = record # TBinaryTree is a generic type with
|
TBinaryTree[T] = object # TBinaryTree is a generic type with
|
||||||
# with generic param ``T``
|
# with generic param ``T``
|
||||||
le, ri: ref TBinaryTree[T] # left and right subtrees; may be nil
|
le, ri: ref TBinaryTree[T] # left and right subtrees; may be nil
|
||||||
data: T # the data stored in a node
|
data: T # the data stored in a node
|
||||||
|
|
@ -1537,7 +1543,8 @@ Modules make separate compilation possible. Each module needs to be in its
|
||||||
own file. Modules enable `information hiding`:idx: and
|
own file. Modules enable `information hiding`:idx: and
|
||||||
`separate compilation`:idx:. A module may gain access to symbols of another
|
`separate compilation`:idx:. A module may gain access to symbols of another
|
||||||
module by the `import`:idx: statement. `Recursive module dependancies`:idx: are
|
module by the `import`:idx: statement. `Recursive module dependancies`:idx: are
|
||||||
allowed, but slightly subtle.
|
allowed, but slightly subtle. Only top-level symbols that are marked with an
|
||||||
|
asterisk (``*``) are exported.
|
||||||
|
|
||||||
The algorithm for compiling modules is:
|
The algorithm for compiling modules is:
|
||||||
|
|
||||||
|
|
@ -1587,13 +1594,13 @@ identifier cannot be redefined in the same block, except if valid for
|
||||||
procedure or iterator overloading purposes.
|
procedure or iterator overloading purposes.
|
||||||
|
|
||||||
|
|
||||||
Record or object scope
|
Tuple or object scope
|
||||||
~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~
|
||||||
The field identifiers inside a record or object definition are valid in the
|
The field identifiers inside a tuple or object definition are valid in the
|
||||||
following places:
|
following places:
|
||||||
|
|
||||||
* To the end of the record definition
|
* To the end of the tuple/object definition
|
||||||
* Field designators of a variable of the given record type.
|
* Field designators of a variable of the given tuple/object type.
|
||||||
* In all descendent types of the object type.
|
* In all descendent types of the object type.
|
||||||
|
|
||||||
Module scope
|
Module scope
|
||||||
|
|
|
||||||
|
|
@ -86,7 +86,7 @@ the C code. Thus it makes the following possible, for example:
|
||||||
|
|
||||||
.. code-block:: Nimrod
|
.. code-block:: Nimrod
|
||||||
var
|
var
|
||||||
EOF {.import: "EOF", no_decl.}: cint # pretend EOF was a variable, as
|
EOF {.importc: "EOF", no_decl.}: cint # pretend EOF was a variable, as
|
||||||
# Nimrod does not know its value
|
# Nimrod does not know its value
|
||||||
|
|
||||||
Varargs Pragma
|
Varargs Pragma
|
||||||
|
|
@ -110,7 +110,7 @@ declared but also that it leads to the inclusion of a given header file:
|
||||||
|
|
||||||
.. code-block:: Nimrod
|
.. code-block:: Nimrod
|
||||||
type
|
type
|
||||||
PFile {.import: "FILE*", header: "<stdio.h>".} = pointer
|
PFile {.importc: "FILE*", header: "<stdio.h>".} = pointer
|
||||||
# import C's FILE* type; Nimrod will treat it as a new pointer type
|
# import C's FILE* type; Nimrod will treat it as a new pointer type
|
||||||
|
|
||||||
The ``header`` pragma expects always a string constant. The string contant
|
The ``header`` pragma expects always a string constant. The string contant
|
||||||
|
|
@ -239,3 +239,28 @@ However it is not efficient to do:
|
||||||
String case statements are optimized too. A hashing scheme is used for them
|
String case statements are optimized too. A hashing scheme is used for them
|
||||||
if several different string constants are used. This is likely to be more
|
if several different string constants are used. This is likely to be more
|
||||||
efficient than any hand-coded scheme.
|
efficient than any hand-coded scheme.
|
||||||
|
|
||||||
|
|
||||||
|
The ECMAScript code generator
|
||||||
|
=============================
|
||||||
|
|
||||||
|
Note: I use the term `ECMAScript`:idx: here instead of `JavaScript`:idx:, since
|
||||||
|
it is the proper term.
|
||||||
|
|
||||||
|
Nimrod targets ECMAScript 1.5 which is supported by any widely used browser.
|
||||||
|
Since ECMAScript does not have a portable means to include another module,
|
||||||
|
Nimrod just generate a long ``.js`` file.
|
||||||
|
|
||||||
|
Features or modules that the ECMAScript platform does not support are not
|
||||||
|
available. This includes:
|
||||||
|
|
||||||
|
* manual memory management (``alloc``, etc.)
|
||||||
|
* casting and other unsafe operations (``cast`` operator, ``zeroMem``, etc.)
|
||||||
|
* file management (``openfile``, etc.)
|
||||||
|
* most modules of the Standard library
|
||||||
|
* proper 64 bit integer arithmetic
|
||||||
|
* proper unsigned integer arithmetic
|
||||||
|
|
||||||
|
However, the modules `strutils`:idx:, `math`:idx:, and `times`:idx: are
|
||||||
|
available! To access the DOM, use the `dom`:idx: module that is only available
|
||||||
|
for the ECMAScript platform.
|
||||||
|
|
|
||||||
220
doc/posix.txt
220
doc/posix.txt
|
|
@ -1,220 +0,0 @@
|
||||||
Function POSIX Description
|
|
||||||
access Tests for file accessibility
|
|
||||||
alarm Schedules an alarm
|
|
||||||
asctime Converts a time structure to a string
|
|
||||||
cfgetispeed Reads terminal input baud rate
|
|
||||||
cfgetospeed Reads terminal output baud rate
|
|
||||||
cfsetispeed Sets terminal input baud rate
|
|
||||||
cfsetospeed Sets terminal output baud rate
|
|
||||||
chdir Changes current working directory
|
|
||||||
chmod Changes file mode
|
|
||||||
chown Changes owner and/or group of a file
|
|
||||||
close Closes a file
|
|
||||||
closedir Ends directory read operation
|
|
||||||
creat Creates a new file or rewrites an existing one
|
|
||||||
ctermid Generates terminal pathname
|
|
||||||
cuserid Gets user name
|
|
||||||
dup Duplicates an open file descriptor
|
|
||||||
dup2 Duplicates an open file descriptor
|
|
||||||
execl Executes a file
|
|
||||||
execle Executes a file
|
|
||||||
execlp Executes a file
|
|
||||||
execv Executes a file
|
|
||||||
execve Executes a file
|
|
||||||
execvp Executes a file
|
|
||||||
_exit Terminates a process
|
|
||||||
fcntl Manipulates an open file descriptor
|
|
||||||
fdopen Opens a stream on a file descriptor
|
|
||||||
fork Creates a process
|
|
||||||
fpathconf Gets configuration variable for an open file
|
|
||||||
fstat Gets file status
|
|
||||||
getcwd Gets current working directory
|
|
||||||
getegid Gets effective group ID
|
|
||||||
getenv Gets environment variable
|
|
||||||
geteuid Gets effective user ID
|
|
||||||
getgid Gets real group ID
|
|
||||||
getgrgid Reads groups database based on group ID
|
|
||||||
getgrnam Reads groups database based on group name
|
|
||||||
getgroups Gets supplementary group IDs
|
|
||||||
getlogin Gets user name
|
|
||||||
getpgrp Gets process group ID
|
|
||||||
getpid Gets process ID
|
|
||||||
getppid Gets parent process ID
|
|
||||||
getpwnam Reads user database based on user name
|
|
||||||
getpwuid Reads user database based on user ID
|
|
||||||
getuid Gets real user ID
|
|
||||||
isatty Determines if a file descriptor is associated with a terminal
|
|
||||||
kill Sends a kill signal to a process
|
|
||||||
link Creates a link to a file
|
|
||||||
longjmp Restores the calling environment
|
|
||||||
lseek Repositions read/write file offset
|
|
||||||
mkdir Makes a directory
|
|
||||||
mkfifo Makes a FIFO special file
|
|
||||||
open Opens a file
|
|
||||||
opendir Opens a directory
|
|
||||||
pathconf Gets configuration variables for a path
|
|
||||||
pause Suspends a process execution
|
|
||||||
pipe Creates an interprocess channel
|
|
||||||
read Reads from a file
|
|
||||||
readdir Reads a directory
|
|
||||||
rename Renames a file
|
|
||||||
rewinddir Resets the readdir() pointer
|
|
||||||
rmdir Removes a directory
|
|
||||||
setgid Sets group ID
|
|
||||||
setjmp Saves the calling environment for use by longjmp()
|
|
||||||
setlocale Sets or queries a program's locale
|
|
||||||
setpgid Sets a process group ID for job control
|
|
||||||
setuid Sets the user ID
|
|
||||||
sigaction Examines and changes signal action
|
|
||||||
sigaddset Adds a signal to a signal set
|
|
||||||
sigdelset Removes a signal to a signal set
|
|
||||||
sigemptyset Creates an empty signal set
|
|
||||||
sigfillset Creates a full set of signals
|
|
||||||
sigismember Tests a signal for a selected member
|
|
||||||
siglongjmp Goes to and restores signal mask
|
|
||||||
sigpending Examines pending signals
|
|
||||||
sigprocmask Examines and changes blocked signals
|
|
||||||
sigsetjmp Saves state for siglongjmp()
|
|
||||||
sigsuspend Waits for a signal
|
|
||||||
sleep Delays process execution
|
|
||||||
stat Gets information about a file
|
|
||||||
sysconf Gets system configuration information
|
|
||||||
tcdrain Waits for all output to be transmitted to the terminal
|
|
||||||
tcflow Suspends/restarts terminal output
|
|
||||||
tcflush Discards terminal data
|
|
||||||
tcgetattr Gets terminal attributes
|
|
||||||
tcgetpgrp Gets foreground process group ID
|
|
||||||
tcsendbreak Sends a break to a terminal
|
|
||||||
tcsetattr Sets terminal attributes
|
|
||||||
tcsetpgrp Sets foreground process group ID
|
|
||||||
time Determines the current calendar time
|
|
||||||
times Gets process times
|
|
||||||
ttyname Determines a terminal pathname
|
|
||||||
tzset Sets the timezone from environment variables
|
|
||||||
umask Sets the file creation mask
|
|
||||||
uname Gets system name
|
|
||||||
unlink Removes a directory entry
|
|
||||||
utime Sets file access and modification times
|
|
||||||
waitpid Waits for process termination
|
|
||||||
write Writes to a file
|
|
||||||
|
|
||||||
|
|
||||||
POSIX.1b function calls Function POSIX Description
|
|
||||||
aio_cancel Tries to cancel an asynchronous operation
|
|
||||||
aio_error Retrieves the error status for an asynchronous operation
|
|
||||||
aio_read Asynchronously reads from a file
|
|
||||||
aio_return Retrieves the return status for an asynchronous operation
|
|
||||||
aio_suspend Waits for an asynchronous operation to complete
|
|
||||||
aio_write Asynchronously writes to a file
|
|
||||||
clock_getres Gets resolution of a POSIX.1b clock
|
|
||||||
clock_gettime Gets the time according to a particular POSIX.1b clock
|
|
||||||
clock_settime Sets the time according to a particular POSIX.1b clock
|
|
||||||
fdatasync Synchronizes at least the data part of a file with the underlying media
|
|
||||||
fsync Synchronizes a file with the underlying media
|
|
||||||
kill, sigqueue Sends signals to a process
|
|
||||||
lio_listio Performs a list of I/O operations, synchronously or asynchronously
|
|
||||||
mlock Locks a range of memory
|
|
||||||
mlockall Locks the entire memory space down
|
|
||||||
mmap Maps a shared memory object (or possibly another file) into process's address space
|
|
||||||
mprotect Changes memory protection on a mapped area
|
|
||||||
mq_close Terminates access to a POSIX.1b message queue
|
|
||||||
mq_getattr Gets POSIX.1b message queue attributes
|
|
||||||
mq_notify Registers a request to be notified when a message arrives on an empty message queue
|
|
||||||
mq_open Creates/accesses a POSIX.1b message queue
|
|
||||||
mq_receive Receives a message from a POSIX.1b message queue
|
|
||||||
mq_send Sends a message on a POSIX.1b message queue
|
|
||||||
mq_setattr Sets a subset of POSIX.1b message queue attributes
|
|
||||||
msync Makes a mapping consistent with the underlying object
|
|
||||||
munlock Unlocks a range of memory
|
|
||||||
munlockall Unlocks the entire address space
|
|
||||||
munmap Undo mapping established by mmap
|
|
||||||
nanosleep Pauses execution for a number of nanoseconds
|
|
||||||
sched_get_priority_max Gets maximum priority value for a scheduler
|
|
||||||
sched_get_priority_min Gets minimum priority value for a scheduler
|
|
||||||
sched_getparam Retrieves scheduling parameters for a particular process
|
|
||||||
sched_getscheduler Retrieves scheduling algorithm for a particular purpose
|
|
||||||
sched_rr_get_interval Gets the SCHED_RR interval for the named process
|
|
||||||
sched_setparam Sets scheduling parameters for a process
|
|
||||||
sched_setscheduler Sets scheduling algorithm/parameters for a process
|
|
||||||
sched_yield Yields the processor
|
|
||||||
sem_close Terminates access to a POSIX.1b semaphore
|
|
||||||
sem_destroy De-initializes a POSIX.1b unnamed semaphore
|
|
||||||
sem_getvalue Gets the value of a POSIX.1b semaphore
|
|
||||||
sem_open Creates/accesses a POSIX.1b named semaphore
|
|
||||||
sem_post Posts (signal) a POSIX.1b named or unnamed semaphore
|
|
||||||
sem_unlink Destroys a POSIX.1b named semaphore
|
|
||||||
sem_wait, sem_trywait Waits on a POSIX.1b named or unnamed semaphore
|
|
||||||
shm_open Creates/accesses a POSIX.1b shared memory object
|
|
||||||
shm_unlink Destroys a POSIX.1b shared memory object
|
|
||||||
sigwaitinfosigtimedwait Synchronously awaits signal arrival; avoid calling handler
|
|
||||||
timer_create Creates a POSIX.1b timer based on a particular clock
|
|
||||||
timer_delete Deletes a POSIX.1b timer
|
|
||||||
timer_gettime Time remaining on a POSIX.1b timer before expiration
|
|
||||||
timer_settime Sets expiration time/interval for a POSIX.1b timer
|
|
||||||
wait, waitpid Retrieves status of a terminated process and clean up corpse
|
|
||||||
|
|
||||||
|
|
||||||
POSIX.1c function calls Function POSIX Description
|
|
||||||
pthread_atfork Declares procedures to be called before and after a fork
|
|
||||||
pthread_attr_destroy Destroys a thread attribute object
|
|
||||||
pthread_attr_getdetachstate Obtains the setting of the detached state of a thread
|
|
||||||
pthread_attr_getinheritsched Obtains the setting of the scheduling inheritance of a thread
|
|
||||||
pthread_attr_getschedparam Obtains the parameters associated with the scheduling policy attribute of a thread
|
|
||||||
pthread_attr_getschedpolicy Obtains the setting of the scheduling policy of a thread
|
|
||||||
pthread_attr_getscope Obtains the setting of the scheduling scope of a thread
|
|
||||||
pthread_attr_getstackaddr Obtains the stack address of a thread
|
|
||||||
pthread_attr_getstacksize Obtains the stack size of a thread
|
|
||||||
pthread_attr_init Initializes a thread attribute object
|
|
||||||
pthread_attr_setdetachstate Adjusts the detached state of a thread
|
|
||||||
pthread_attr_setinheritsched Adjusts the scheduling inheritance of a thread
|
|
||||||
pthread_attr_setschedparam Adjusts the parameters associated with the scheduling policy of a thread
|
|
||||||
pthread_attr_setschedpolicy Adjusts the scheduling policy of a thread
|
|
||||||
pthread_attr_setscope Adjusts the scheduling scope of a thread
|
|
||||||
pthread_attr_setstackaddr Adjusts the stack address of a thread
|
|
||||||
pthread_attr_setstacksize Adjusts the stack size of a thread
|
|
||||||
pthread_cancel Cancels the specific thread
|
|
||||||
pthread_cleanup_pop Removes the routine from the top of a thread's cleanup stack, and if execute is nonzero, runs it
|
|
||||||
pthread_cleanup_push Places a routine on the top of a thread's cleanup stack
|
|
||||||
pthread_condattr_destroy Destroys a condition variable attribute object
|
|
||||||
pthread_condattr_getpshared Obtains the process-shared setting of a condition variable attribute object
|
|
||||||
pthread_condattr_init Initializes a condition variable attribute object
|
|
||||||
pthread_condattr_setpshared Sets the process-shared attribute in a condition variable attribute object to either PTHREAD_PROCESS_SHARED or PTHREAD_PROCESS_PRIVATE
|
|
||||||
pthread_cond_broadcast Unblocks all threads that are waiting on a condition variable
|
|
||||||
pthread_cond_destroy Destroys a condition variable
|
|
||||||
pthread_cond_init Initializes a condition variable with the attributes specified in the specified condition variable attribute object
|
|
||||||
pthread_cond_signal Unblocks at least one thread waiting on a condition variable
|
|
||||||
pthread_cond_timedwait Automatically unlocks the specified mutex, and places the calling thread into a wait state
|
|
||||||
pthread_cond_wait Automatically unlocks the specified mutex, and places the calling thread into a wait state
|
|
||||||
pthread_create Creates a thread with the attributes specified in attr
|
|
||||||
pthread_detach Marks a threads internal data structures for deletion
|
|
||||||
pthread_equal Compares one thread handle to another thread handle
|
|
||||||
pthread_exit Terminates the calling thread
|
|
||||||
pthread_getschedparam Obtains both scheduling policy and scheduling parameters of an existing thread
|
|
||||||
pthread_getspecific Obtains the thread specific data value associated with the specific key in the calling thread
|
|
||||||
pthread_join Causes the calling thread to wait for the specific thread’s termination
|
|
||||||
pthread_key_create Generates a unique thread-specific key that's visible to all threads in a process
|
|
||||||
pthread_key_delete Deletes a thread specific key
|
|
||||||
pthread_kill Delivers a signal to the specified thread
|
|
||||||
pthread_mutexattr_destroy Destroys a mutex attribute object
|
|
||||||
pthread_mutexattr_getprioceiling Obtains the priority ceiling of a mutex attribute object
|
|
||||||
pthread_mutexattr_getprotocol Obtains protocol of a mutex attribute object
|
|
||||||
pthread_mutexattr_getpshared Obtains a process-shared setting of a mutex attribute object
|
|
||||||
pthread_mutexattr_init Initializes a mutex attribute object
|
|
||||||
pthread_mutexattr_setprioceiling Sets the priority ceiling attribute of a mutex attribute object
|
|
||||||
pthread_mutexattr_setprotocol Sets the protocol attribute of a mutex attribute object
|
|
||||||
pthread_mutexattr_setpshared Sets the process-shared attribute of a mutex attribute object to either PTHREAD_PROCESS_SHARED or PTHREAD_PROCESS_PRIVATE
|
|
||||||
pthread_mutex_destroy Destroys a mutex
|
|
||||||
pthread_mutex_init Initializes a mutex with the attributes specified in the specified mutex attribute object
|
|
||||||
pthread_mutex_lock Locks an unlocked mutex
|
|
||||||
pthread_mutex_trylock Tries to lock a not tested
|
|
||||||
pthread_mutex_unlock Unlocks a mutex
|
|
||||||
pthread_once Ensures that init_routine will run just once regardless of how many threads in the process call it
|
|
||||||
pthread_self Obtains a thread handle of a calling thread
|
|
||||||
pthread_setcancelstate Sets a thread's cancelability state
|
|
||||||
pthread_setcanceltype Sets a thread's cancelability type
|
|
||||||
pthread_setschedparam Adjusts the scheduling policy and scheduling parameters of an existing thread
|
|
||||||
pthread_setspecific Sets the thread-specific data value associated with the specific key in the calling thread
|
|
||||||
pthread_sigmask Examines or changes the calling thread's signal mask
|
|
||||||
pthread_testcancel Requests that any pending cancellation request be delivered to the calling thread
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -4,8 +4,4 @@ Nimrod's documenation system
|
||||||
|
|
||||||
This folder contains Nimrod's documentation. The documentation
|
This folder contains Nimrod's documentation. The documentation
|
||||||
is written in a format called *reStructuredText*, a markup language that reads
|
is written in a format called *reStructuredText*, a markup language that reads
|
||||||
like ASCII and can be converted to HTML, Tex and other formats automatically!
|
like ASCII and can be converted to HTML automatically!
|
||||||
|
|
||||||
Unfortunately reStructuredText does not allow to colorize source code in the
|
|
||||||
HTML page. Therefore a postprocessor runs over the generated HTML code, looking
|
|
||||||
for Nimrod code fragments and colorizing them.
|
|
||||||
|
|
|
||||||
|
|
@ -272,25 +272,3 @@ end of the subject string, whatever options are set.
|
||||||
The difference between ``\Z`` and ``\z`` is that ``\Z`` matches before
|
The difference between ``\Z`` and ``\z`` is that ``\Z`` matches before
|
||||||
a newline that is the last character of the string as well as at the end
|
a newline that is the last character of the string as well as at the end
|
||||||
of the string, whereas ``\z`` matches only at the end.
|
of the string, whereas ``\z`` matches only at the end.
|
||||||
|
|
||||||
..
|
|
||||||
Regular expressions in Nimrod itself!
|
|
||||||
-------------------------------------
|
|
||||||
|
|
||||||
'a' -- matches the character a
|
|
||||||
'a'-'z' -- range operator '-'
|
|
||||||
'A' | 'B' -- alternative operator |
|
|
||||||
* 'a' -- prefix * is needed
|
|
||||||
+ 'a' -- prefix + is needed
|
|
||||||
? 'a' -- prefix ? is needed
|
|
||||||
letter -- character classes with real names!
|
|
||||||
letters
|
|
||||||
white
|
|
||||||
whites
|
|
||||||
any -- any character
|
|
||||||
() -- are Nimrod syntax
|
|
||||||
! 'a'-'z'
|
|
||||||
|
|
||||||
-- concatentation via proc call:
|
|
||||||
|
|
||||||
re('A' 'Z' word * )
|
|
||||||
|
|
|
||||||
3856
doc/theindex.txt
3856
doc/theindex.txt
File diff suppressed because it is too large
Load diff
|
|
@ -85,13 +85,13 @@ We start the tour with a modified "hallo world" program:
|
||||||
|
|
||||||
Save this code to the file "greeting.nim". Now compile and run it::
|
Save this code to the file "greeting.nim". Now compile and run it::
|
||||||
|
|
||||||
nimrod run greeting.nim
|
nimrod compile --run greeting.nim
|
||||||
|
|
||||||
As you see, with the ``run`` command Nimrod executes the file automatically
|
As you see, with the ``--run`` switch Nimrod executes the file automatically
|
||||||
after compilation. You can even give your program command line arguments by
|
after compilation. You can even give your program command line arguments by
|
||||||
appending them after the filename that is to be compiled and run::
|
appending them after the filename that is to be compiled and run::
|
||||||
|
|
||||||
nimrod run greeting.nim arg1 arg2
|
nimrod compile --run greeting.nim arg1 arg2
|
||||||
|
|
||||||
Though it should be pretty obvious what the program does, I will explain the
|
Though it should be pretty obvious what the program does, I will explain the
|
||||||
syntax: Statements which are not indented are executed when the program
|
syntax: Statements which are not indented are executed when the program
|
||||||
|
|
@ -198,7 +198,7 @@ An example showing the most common statement types:
|
||||||
|
|
||||||
.. code-block:: Nimrod
|
.. code-block:: Nimrod
|
||||||
type
|
type
|
||||||
TMyRecord = record
|
TMyRecord = object
|
||||||
x, y: int
|
x, y: int
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
284
ide/main.nim
284
ide/main.nim
|
|
@ -1,60 +1,35 @@
|
||||||
|
|
||||||
import glib2, gtk2, libglade2
|
import glib2, gtk2, libglade2, dialogs
|
||||||
|
|
||||||
proc on_window_destroy(obj: PGtkObject, data: pointer) {.exportc, cdecl.} =
|
proc on_window_destroy(obj: PGtkObject, data: pointer) {.cdecl.} =
|
||||||
gtk_main_quit()
|
gtk_main_quit()
|
||||||
|
|
||||||
const
|
const
|
||||||
GuiTemplate = "/media/hda4/nimrod/ide/nimide.glade"
|
GuiTemplate = "/media/hda4/nimrod/ide/nimide.glade"
|
||||||
|
|
||||||
type
|
type
|
||||||
TMyTextEditor = record
|
TTab = object of TObject
|
||||||
|
textview: PGtkTextView
|
||||||
|
filename: string
|
||||||
|
untitled: bool
|
||||||
|
|
||||||
|
TMyTextEditor = object of TObject
|
||||||
window: PGtkWindow
|
window: PGtkWindow
|
||||||
statusbar: PGtkStatusBar
|
statusbar: PGtkStatusBar
|
||||||
textview: PGtkTextview
|
textview: PGtkTextview
|
||||||
statusbarContextId: int
|
statusbarContextId: int
|
||||||
filename: string
|
|
||||||
|
|
||||||
proc error_message(msg: string) =
|
|
||||||
var
|
|
||||||
dialog: PGtkDialog
|
|
||||||
dialog = GTK_DIALOG(gtk_message_dialog_new(nil,
|
|
||||||
GTK_DIALOG_MODAL or GTK_DIALOG_DESTROY_WITH_PARENT,
|
|
||||||
GTK_MESSAGE_ERROR, GTK_BUTTONS_OK, msg))
|
|
||||||
|
|
||||||
gtk_window_set_title(dialog, "Error!")
|
|
||||||
gtk_dialog_run(dialog)
|
|
||||||
gtk_widget_destroy(dialog)
|
|
||||||
|
|
||||||
|
|
||||||
proc get_open_filename(e: TMyTextEditor): string =
|
|
||||||
var
|
|
||||||
chooser: PGtkDialog
|
|
||||||
chooser = gtk_file_chooser_dialog_new("Open File...", e.window,
|
|
||||||
GTK_FILE_CHOOSER_ACTION_OPEN,
|
|
||||||
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
|
|
||||||
GTK_STOCK_OPEN, GTK_RESPONSE_OK, nil)
|
|
||||||
|
|
||||||
if gtk_dialog_run(chooser) == GTK_RESPONSE_OK:
|
proc on_about_menu_item_activate(menuItem: PGtkMenuItem,
|
||||||
result = $gtk_file_chooser_get_filename(chooser)
|
e: var TMyTextEditor) {.cdecl.} =
|
||||||
else:
|
gtk_show_about_dialog(e.window,
|
||||||
result = ""
|
"comments", "A fast and leight-weight IDE for Nimrod",
|
||||||
gtk_widget_destroy(chooser)
|
"copyright", "Copyright \xc2\xa9 2008 Andreas Rumpf",
|
||||||
|
"version", "0.1",
|
||||||
|
"website", "http://nimrod.ethexor.com",
|
||||||
proc get_save_filename(e: TMyTextEditor): string =
|
"program-name", "Nimrod IDE",
|
||||||
var
|
nil)
|
||||||
chooser: PGtkDialog
|
|
||||||
chooser = gtk_file_chooser_dialog_new("Save File...", e.window,
|
|
||||||
GTK_FILE_CHOOSER_ACTION_SAVE,
|
|
||||||
GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
|
|
||||||
GTK_STOCK_OPEN, GTK_RESPONSE_OK, nil)
|
|
||||||
|
|
||||||
if gtk_dialog_run(chooser) == GTK_RESPONSE_OK:
|
|
||||||
result = $gtk_file_chooser_get_filename(chooser)
|
|
||||||
else:
|
|
||||||
result = ""
|
|
||||||
gtk_widget_destroy(chooser)
|
|
||||||
|
|
||||||
proc load_file(e: var TMyTextEditor, filename: string) =
|
proc load_file(e: var TMyTextEditor, filename: string) =
|
||||||
var
|
var
|
||||||
|
|
@ -119,6 +94,21 @@ proc write_file(e: var TMyTextEditor, filename: string) =
|
||||||
reset_default_status(editor)
|
reset_default_status(editor)
|
||||||
|
|
||||||
|
|
||||||
|
proc check_for_save(e: var TMyTextEditor): bool =
|
||||||
|
GtkTextBuffer *buffer;
|
||||||
|
buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (editor->text_view));
|
||||||
|
if gtk_text_buffer_get_modified(buffer):
|
||||||
|
GtkWidget *dialog;
|
||||||
|
const gchar *msg = "Do you want to save the changes you have made?";
|
||||||
|
dialog = gtk_message_dialog_new (nil,
|
||||||
|
GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
|
||||||
|
GTK_MESSAGE_QUESTION,
|
||||||
|
GTK_BUTTONS_YES_NO,
|
||||||
|
msg);
|
||||||
|
gtk_window_set_title (GTK_WINDOW (dialog), "Save?");
|
||||||
|
result = gtk_dialog_run(dialog) != GTK_RESPONSE_NO
|
||||||
|
gtk_widget_destroy(dialog)
|
||||||
|
|
||||||
proc initApp(e: var TMyTextEditor) =
|
proc initApp(e: var TMyTextEditor) =
|
||||||
var
|
var
|
||||||
builder: PGladeXML
|
builder: PGladeXML
|
||||||
|
|
@ -136,7 +126,7 @@ proc initApp(e: var TMyTextEditor) =
|
||||||
|
|
||||||
# connect the signal handlers:
|
# connect the signal handlers:
|
||||||
glade_xml_signal_connect(builder, "on_window_destroy",
|
glade_xml_signal_connect(builder, "on_window_destroy",
|
||||||
cast[TGCallback](on_window_destroy))
|
GCallback(on_window_destroy))
|
||||||
|
|
||||||
font_desc = pango_font_description_from_string("monospace 10")
|
font_desc = pango_font_description_from_string("monospace 10")
|
||||||
gtk_widget_modify_font(e.textview, font_desc)
|
gtk_widget_modify_font(e.textview, font_desc)
|
||||||
|
|
@ -162,208 +152,82 @@ proc main() =
|
||||||
main()
|
main()
|
||||||
|
|
||||||
|
|
||||||
proc reset_default_status(e: var TMyTextEditor)
|
|
||||||
gchar *file;
|
|
||||||
gchar *status;
|
|
||||||
|
|
||||||
if e.filename == "":
|
proc on_window_delete_event(widget: PGtkWidget, event: PGdkEvent,
|
||||||
file = g_strdup("(UNTITLED)")
|
e: TMyTextEditor): bool {.cdecl.} =
|
||||||
else:
|
if check_for_save(editor):
|
||||||
file = g_path_get_basename(editor->filename)
|
on_save_menu_item_activate(nil, editor)
|
||||||
|
result = false
|
||||||
|
|
||||||
status = g_strdup_printf("File: %s", file)
|
proc on_new_menu_item_activate(GtkMenuItem *menuitem, TutorialTextEditor *editor)
|
||||||
gtk_statusbar_pop(e.statusbar,
|
|
||||||
e.statusbar_context_id)
|
|
||||||
gtk_statusbar_push(e.statusbar,
|
|
||||||
e.statusbar_context_id, status)
|
|
||||||
g_free(status)
|
|
||||||
g_free(file)
|
|
||||||
|
|
||||||
|
|
||||||
gboolean
|
|
||||||
check_for_save(e: var TMyTextEditor)
|
|
||||||
gboolean ret = FALSE;
|
|
||||||
GtkTextBuffer *buffer;
|
|
||||||
buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (editor->text_view));
|
|
||||||
if (gtk_text_buffer_get_modified (buffer) == TRUE)
|
|
||||||
{
|
|
||||||
GtkWidget *dialog;
|
|
||||||
const gchar *msg = "Do you want to save the changes you have made?";
|
|
||||||
dialog = gtk_message_dialog_new (NULL,
|
|
||||||
GTK_DIALOG_MODAL | GTK_DIALOG_DESTROY_WITH_PARENT,
|
|
||||||
GTK_MESSAGE_QUESTION,
|
|
||||||
GTK_BUTTONS_YES_NO,
|
|
||||||
msg);
|
|
||||||
gtk_window_set_title (GTK_WINDOW (dialog), "Save?");
|
|
||||||
if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_NO)
|
|
||||||
{
|
|
||||||
ret = FALSE;
|
|
||||||
} else ret = TRUE;
|
|
||||||
gtk_widget_destroy (dialog);
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
When the window is requested to be closed, we need to check if they have
|
|
||||||
unsaved work. We use this callback to prompt the user to save their work before
|
|
||||||
they exit the application. From the "delete-event" signal, we can choose to
|
|
||||||
effectively cancel the close based on the value we return.
|
|
||||||
*/
|
|
||||||
gboolean
|
|
||||||
on_window_delete_event(GtkWidget *widget, GdkEvent *event,
|
|
||||||
TutorialTextEditor *editor)
|
|
||||||
{
|
|
||||||
if (check_for_save (editor) == TRUE)
|
|
||||||
on_save_menu_item_activate (NULL, editor);
|
|
||||||
return FALSE; /* propogate event */
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
Called when the user clicks the 'New' menu. We need to prompt for save if the
|
|
||||||
file has been modified, and then delete the buffer and clear the modified flag.
|
|
||||||
*/
|
|
||||||
void on_new_menu_item_activate (GtkMenuItem *menuitem, TutorialTextEditor *editor)
|
|
||||||
{
|
|
||||||
GtkTextBuffer *buffer;
|
GtkTextBuffer *buffer;
|
||||||
|
|
||||||
if (check_for_save (editor) == TRUE)
|
if check_for_save(editor):
|
||||||
{
|
on_save_menu_item_activate(nil, editor)
|
||||||
on_save_menu_item_activate (NULL, editor);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* clear editor for a new file */
|
/* clear editor for a new file */
|
||||||
editor->filename = NULL;
|
editor->filename = nil;
|
||||||
buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW (editor->text_view));
|
buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW (editor->text_view));
|
||||||
gtk_text_buffer_set_text(buffer, "", -1);
|
gtk_text_buffer_set_text(buffer, "", -1);
|
||||||
gtk_text_buffer_set_modified(buffer, FALSE);
|
gtk_text_buffer_set_modified(buffer, FALSE);
|
||||||
|
|
||||||
reset_default_status(editor);
|
reset_default_status(editor);
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
Called when the user clicks the 'Open' menu. We need to prompt for save if the
|
proc on_open_menu_item_activate(menuItem: PGtkMenuItem,
|
||||||
file has been modified, allow the user to choose a file to open, and then call
|
TutorialTextEditor *editor) =
|
||||||
load_file() on that file.
|
|
||||||
*/
|
|
||||||
void on_open_menu_item_activate (GtkMenuItem *menuitem, TutorialTextEditor *editor)
|
|
||||||
{
|
|
||||||
gchar *filename;
|
gchar *filename;
|
||||||
|
|
||||||
if (check_for_save (editor) == TRUE)
|
if check_for_save(editor):
|
||||||
{
|
on_save_menu_item_activate(nil, editor)
|
||||||
on_save_menu_item_activate (NULL, editor);
|
filename = get_open_filename(editor)
|
||||||
}
|
if filename != nil: load_file(editor, filename)
|
||||||
|
|
||||||
filename = get_open_filename (editor);
|
proc on_save_menu_item_activate(menuItem: PGtkMenuItem, TutorialTextEditor *editor) =
|
||||||
if (filename != NULL) load_file (editor, filename);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
Called when the user clicks the 'Save' menu. We need to allow the user to choose
|
|
||||||
a file to save if it's an untitled document, and then call write_file() on that
|
|
||||||
file.
|
|
||||||
*/
|
|
||||||
void on_save_menu_item_activate (GtkMenuItem *menuitem, TutorialTextEditor *editor)
|
|
||||||
{
|
|
||||||
gchar *filename;
|
gchar *filename;
|
||||||
|
if (editor->filename == nil)
|
||||||
if (editor->filename == NULL)
|
|
||||||
{
|
{
|
||||||
filename = get_save_filename(editor);
|
filename = get_save_filename(editor);
|
||||||
if (filename != NULL) write_file (editor, filename);
|
if (filename != nil) write_file(editor, filename);
|
||||||
}
|
}
|
||||||
else write_file (editor, NULL);
|
else write_file(editor, nil);
|
||||||
|
|
||||||
}
|
proc on_save_as_menu_item_activate(GtkMenuItem *menuitem,
|
||||||
|
TutorialTextEditor *editor) =
|
||||||
/*
|
|
||||||
Called when the user clicks the 'Save As' menu. We need to allow the user to
|
|
||||||
choose a file to save and then call write_file() on that file.
|
|
||||||
*/
|
|
||||||
void on_save_as_menu_item_activate (GtkMenuItem *menuitem, TutorialTextEditor *editor)
|
|
||||||
{
|
|
||||||
gchar *filename;
|
gchar *filename;
|
||||||
|
|
||||||
filename = get_save_filename (editor);
|
filename = get_save_filename(editor)
|
||||||
if (filename != NULL) write_file (editor, filename);
|
if filename != nil: write_file(editor, filename)
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
proc on_quit_menu_item_activate(GtkMenuItem *menuitem, TutorialTextEditor *editor)
|
||||||
Called when the user clicks the 'Quit' menu. We need to prompt for save if the
|
if check_for_save(editor):
|
||||||
file has been modified and then break out of the GTK+ main loop.
|
on_save_menu_item_activate(nil, editor)
|
||||||
*/
|
gtk_main_quit()
|
||||||
void on_quit_menu_item_activate (GtkMenuItem *menuitem, TutorialTextEditor *editor)
|
|
||||||
{
|
|
||||||
if (check_for_save (editor) == TRUE)
|
|
||||||
{
|
|
||||||
on_save_menu_item_activate (NULL, editor);
|
|
||||||
}
|
|
||||||
gtk_main_quit();
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
proc on_cut_menu_item_activate(GtkMenuItem *menuitem, TutorialTextEditor *editor) =
|
||||||
Called when the user clicks the 'Cut' menu.
|
|
||||||
*/
|
|
||||||
void on_cut_menu_item_activate (GtkMenuItem *menuitem, TutorialTextEditor *editor)
|
|
||||||
{
|
|
||||||
GtkTextBuffer *buffer;
|
GtkTextBuffer *buffer;
|
||||||
GtkClipboard *clipboard;
|
GtkClipboard *clipboard;
|
||||||
|
|
||||||
clipboard = gtk_clipboard_get(GDK_SELECTION_CLIPBOARD);
|
clipboard = gtk_clipboard_get(GDK_SELECTION_CLIPBOARD);
|
||||||
buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (editor->text_view));
|
buffer = gtk_text_view_get_buffer(editor->text_view)
|
||||||
gtk_text_buffer_cut_clipboard (buffer, clipboard, TRUE);
|
gtk_text_buffer_cut_clipboard(buffer, clipboard, TRUE)
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
proc on_copy_menu_item_activate(GtkMenuItem *menuitem, TutorialTextEditor *editor) =
|
||||||
Called when the user clicks the 'Copy' menu.
|
|
||||||
*/
|
|
||||||
void on_copy_menu_item_activate (GtkMenuItem *menuitem, TutorialTextEditor *editor)
|
|
||||||
{
|
|
||||||
GtkTextBuffer *buffer;
|
GtkTextBuffer *buffer;
|
||||||
GtkClipboard *clipboard;
|
GtkClipboard *clipboard;
|
||||||
|
clipboard = gtk_clipboard_get(GDK_SELECTION_CLIPBOARD)
|
||||||
|
buffer = gtk_text_view_get_buffer(editor->text_view)
|
||||||
|
gtk_text_buffer_copy_clipboard(buffer, clipboard)
|
||||||
|
|
||||||
clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
|
|
||||||
buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (editor->text_view));
|
|
||||||
gtk_text_buffer_copy_clipboard (buffer, clipboard);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
proc on_paste_menu_item_activate(GtkMenuItem *menuitem, TutorialTextEditor *editor)
|
||||||
Called when the user clicks the 'Paste' menu.
|
|
||||||
*/
|
|
||||||
void on_paste_menu_item_activate (GtkMenuItem *menuitem, TutorialTextEditor *editor)
|
|
||||||
{
|
|
||||||
GtkTextBuffer *buffer;
|
GtkTextBuffer *buffer;
|
||||||
GtkClipboard *clipboard;
|
GtkClipboard *clipboard;
|
||||||
clipboard = gtk_clipboard_get (GDK_SELECTION_CLIPBOARD);
|
clipboard = gtk_clipboard_get(GDK_SELECTION_CLIPBOARD)
|
||||||
buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (editor->text_view));
|
buffer = gtk_text_view_get_buffer(editor->text_view)
|
||||||
gtk_text_buffer_paste_clipboard (buffer, clipboard, NULL, TRUE);
|
gtk_text_buffer_paste_clipboard(buffer, clipboard, nil, TRUE)
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
proc on_delete_menu_item_activate(GtkMenuItem *menuitem, TutorialTextEditor *editor)
|
||||||
Called when the user clicks the 'Delete' menu.
|
|
||||||
*/
|
|
||||||
void on_delete_menu_item_activate (GtkMenuItem *menuitem, TutorialTextEditor *editor)
|
|
||||||
{
|
|
||||||
GtkTextBuffer *buffer;
|
GtkTextBuffer *buffer;
|
||||||
buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (editor->text_view));
|
buffer = gtk_text_view_get_buffer(editor->text_view);
|
||||||
gtk_text_buffer_delete_selection(buffer, FALSE, TRUE);
|
gtk_text_buffer_delete_selection(buffer, FALSE, TRUE);
|
||||||
}
|
|
||||||
|
|
||||||
void on_about_menu_item_activate (GtkMenuItem *menuitem, TutorialTextEditor *editor)
|
|
||||||
{
|
|
||||||
static const gchar * const authors[] = {
|
|
||||||
"Micah Carrick <email@micahcarrick.com>",
|
|
||||||
NULL
|
|
||||||
};
|
|
||||||
static const gchar copyright[] = "Copyright \xc2\xa9 2008 Andreas Rumpf";
|
|
||||||
static const gchar comments[] = "GTK+ and Glade3 GUI Programming Tutorial";
|
|
||||||
gtk_show_about_dialog (e.window,
|
|
||||||
"authors", authors,
|
|
||||||
"comments", comments,
|
|
||||||
"copyright", copyright,
|
|
||||||
"version", "0.1",
|
|
||||||
"website", "http://www.micahcarrick.com",
|
|
||||||
"program-name", "GTK+ Text Editor",
|
|
||||||
"logo-icon-name", GTK_STOCK_EDIT, nil)
|
|
||||||
}
|
|
||||||
|
|
|
||||||
105
ide/nimide.glade
105
ide/nimide.glade
|
|
@ -1,66 +1,91 @@
|
||||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
<?xml version="1.0" standalone="no"?> <!--*- mode: xml -*-->
|
||||||
<!DOCTYPE glade-interface SYSTEM "glade-2.0.dtd">
|
<!DOCTYPE glade-interface SYSTEM "http://glade.gnome.org/glade-2.0.dtd">
|
||||||
<!--Generated with glade3 3.4.2 on Sat Jun 21 14:12:42 2008 -->
|
|
||||||
<glade-interface>
|
<glade-interface>
|
||||||
|
|
||||||
<widget class="GtkWindow" id="window">
|
<widget class="GtkWindow" id="window">
|
||||||
<property name="extension_events">GDK_EXTENSION_EVENTS_ALL</property>
|
<property name="extension_events">GDK_EXTENSION_EVENTS_ALL</property>
|
||||||
|
<property name="title" translatable="yes"></property>
|
||||||
|
<property name="type">GTK_WINDOW_TOPLEVEL</property>
|
||||||
|
<property name="window_position">GTK_WIN_POS_NONE</property>
|
||||||
|
<property name="modal">False</property>
|
||||||
|
<property name="resizable">True</property>
|
||||||
|
<property name="destroy_with_parent">False</property>
|
||||||
|
<property name="decorated">True</property>
|
||||||
|
<property name="skip_taskbar_hint">False</property>
|
||||||
|
<property name="skip_pager_hint">False</property>
|
||||||
|
<property name="type_hint">GDK_WINDOW_TYPE_HINT_NORMAL</property>
|
||||||
|
<property name="gravity">GDK_GRAVITY_NORTH_WEST</property>
|
||||||
|
<property name="focus_on_map">True</property>
|
||||||
|
<property name="urgency_hint">False</property>
|
||||||
<signal name="destroy" handler="on_window_destroy" object="destroy"/>
|
<signal name="destroy" handler="on_window_destroy" object="destroy"/>
|
||||||
|
|
||||||
<child>
|
<child>
|
||||||
<widget class="GtkVBox" id="mainvbox">
|
<widget class="GtkVBox" id="mainvbox">
|
||||||
|
<property name="width_request">600</property>
|
||||||
|
<property name="height_request">400</property>
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
|
<property name="homogeneous">False</property>
|
||||||
|
<property name="spacing">0</property>
|
||||||
|
|
||||||
<child>
|
<child>
|
||||||
<widget class="GtkMenuBar" id="menubar">
|
<widget class="GtkMenuBar" id="menubar">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
|
<property name="pack_direction">GTK_PACK_DIRECTION_LTR</property>
|
||||||
|
<property name="child_pack_direction">GTK_PACK_DIRECTION_LTR</property>
|
||||||
|
|
||||||
<child>
|
<child>
|
||||||
<widget class="GtkMenuItem" id="menuitem1">
|
<widget class="GtkMenuItem" id="menuitem1">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="label" translatable="yes">_Datei</property>
|
<property name="label" translatable="yes">_Datei</property>
|
||||||
<property name="use_underline">True</property>
|
<property name="use_underline">True</property>
|
||||||
|
|
||||||
<child>
|
<child>
|
||||||
<widget class="GtkMenu" id="menu1">
|
<widget class="GtkMenu" id="menu1">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
|
|
||||||
<child>
|
<child>
|
||||||
<widget class="GtkImageMenuItem" id="new_menu_item">
|
<widget class="GtkImageMenuItem" id="new_menu_item">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="label" translatable="yes">gtk-new</property>
|
<property name="label">gtk-new</property>
|
||||||
<property name="use_underline">True</property>
|
|
||||||
<property name="use_stock">True</property>
|
<property name="use_stock">True</property>
|
||||||
</widget>
|
</widget>
|
||||||
</child>
|
</child>
|
||||||
|
|
||||||
<child>
|
<child>
|
||||||
<widget class="GtkImageMenuItem" id="open_menu_item">
|
<widget class="GtkImageMenuItem" id="open_menu_item">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="label" translatable="yes">gtk-open</property>
|
<property name="label">gtk-open</property>
|
||||||
<property name="use_underline">True</property>
|
|
||||||
<property name="use_stock">True</property>
|
<property name="use_stock">True</property>
|
||||||
</widget>
|
</widget>
|
||||||
</child>
|
</child>
|
||||||
|
|
||||||
<child>
|
<child>
|
||||||
<widget class="GtkImageMenuItem" id="save_menu_item">
|
<widget class="GtkImageMenuItem" id="save_menu_item">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="label" translatable="yes">gtk-save</property>
|
<property name="label">gtk-save</property>
|
||||||
<property name="use_underline">True</property>
|
|
||||||
<property name="use_stock">True</property>
|
<property name="use_stock">True</property>
|
||||||
</widget>
|
</widget>
|
||||||
</child>
|
</child>
|
||||||
|
|
||||||
<child>
|
<child>
|
||||||
<widget class="GtkImageMenuItem" id="save_as_menu_item">
|
<widget class="GtkImageMenuItem" id="save_as_menu_item">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="label" translatable="yes">gtk-save-as</property>
|
<property name="label">gtk-save-as</property>
|
||||||
<property name="use_underline">True</property>
|
|
||||||
<property name="use_stock">True</property>
|
<property name="use_stock">True</property>
|
||||||
</widget>
|
</widget>
|
||||||
</child>
|
</child>
|
||||||
|
|
||||||
<child>
|
<child>
|
||||||
<widget class="GtkSeparatorMenuItem" id="separatormenuitem1">
|
<widget class="GtkSeparatorMenuItem" id="separatormenuitem1">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
</widget>
|
</widget>
|
||||||
</child>
|
</child>
|
||||||
|
|
||||||
<child>
|
<child>
|
||||||
<widget class="GtkImageMenuItem" id="quit_menu_item">
|
<widget class="GtkImageMenuItem" id="quit_menu_item">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="label" translatable="yes">gtk-quit</property>
|
<property name="label">gtk-quit</property>
|
||||||
<property name="use_underline">True</property>
|
|
||||||
<property name="use_stock">True</property>
|
<property name="use_stock">True</property>
|
||||||
</widget>
|
</widget>
|
||||||
</child>
|
</child>
|
||||||
|
|
@ -68,43 +93,45 @@
|
||||||
</child>
|
</child>
|
||||||
</widget>
|
</widget>
|
||||||
</child>
|
</child>
|
||||||
|
|
||||||
<child>
|
<child>
|
||||||
<widget class="GtkMenuItem" id="menuitem2">
|
<widget class="GtkMenuItem" id="menuitem2">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="label" translatable="yes">_Bearbeiten</property>
|
<property name="label" translatable="yes">_Bearbeiten</property>
|
||||||
<property name="use_underline">True</property>
|
<property name="use_underline">True</property>
|
||||||
|
|
||||||
<child>
|
<child>
|
||||||
<widget class="GtkMenu" id="menu2">
|
<widget class="GtkMenu" id="menu2">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
|
|
||||||
<child>
|
<child>
|
||||||
<widget class="GtkImageMenuItem" id="cut_menu_item">
|
<widget class="GtkImageMenuItem" id="cut_menu_item">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="label" translatable="yes">gtk-cut</property>
|
<property name="label">gtk-cut</property>
|
||||||
<property name="use_underline">True</property>
|
|
||||||
<property name="use_stock">True</property>
|
<property name="use_stock">True</property>
|
||||||
</widget>
|
</widget>
|
||||||
</child>
|
</child>
|
||||||
|
|
||||||
<child>
|
<child>
|
||||||
<widget class="GtkImageMenuItem" id="copy_menu_item">
|
<widget class="GtkImageMenuItem" id="copy_menu_item">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="label" translatable="yes">gtk-copy</property>
|
<property name="label">gtk-copy</property>
|
||||||
<property name="use_underline">True</property>
|
|
||||||
<property name="use_stock">True</property>
|
<property name="use_stock">True</property>
|
||||||
</widget>
|
</widget>
|
||||||
</child>
|
</child>
|
||||||
|
|
||||||
<child>
|
<child>
|
||||||
<widget class="GtkImageMenuItem" id="paste_menu_item">
|
<widget class="GtkImageMenuItem" id="paste_menu_item">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="label" translatable="yes">gtk-paste</property>
|
<property name="label">gtk-paste</property>
|
||||||
<property name="use_underline">True</property>
|
|
||||||
<property name="use_stock">True</property>
|
<property name="use_stock">True</property>
|
||||||
</widget>
|
</widget>
|
||||||
</child>
|
</child>
|
||||||
|
|
||||||
<child>
|
<child>
|
||||||
<widget class="GtkImageMenuItem" id="delete_menu_item">
|
<widget class="GtkImageMenuItem" id="delete_menu_item">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="label" translatable="yes">gtk-delete</property>
|
<property name="label">gtk-delete</property>
|
||||||
<property name="use_underline">True</property>
|
|
||||||
<property name="use_stock">True</property>
|
<property name="use_stock">True</property>
|
||||||
</widget>
|
</widget>
|
||||||
</child>
|
</child>
|
||||||
|
|
@ -112,19 +139,21 @@
|
||||||
</child>
|
</child>
|
||||||
</widget>
|
</widget>
|
||||||
</child>
|
</child>
|
||||||
|
|
||||||
<child>
|
<child>
|
||||||
<widget class="GtkMenuItem" id="menuitem4">
|
<widget class="GtkMenuItem" id="menuitem4">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="label" translatable="yes">_Hilfe</property>
|
<property name="label" translatable="yes">_Hilfe</property>
|
||||||
<property name="use_underline">True</property>
|
<property name="use_underline">True</property>
|
||||||
|
|
||||||
<child>
|
<child>
|
||||||
<widget class="GtkMenu" id="menu3">
|
<widget class="GtkMenu" id="menu3">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
|
|
||||||
<child>
|
<child>
|
||||||
<widget class="GtkImageMenuItem" id="about_menu_item">
|
<widget class="GtkImageMenuItem" id="about_menu_item">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="label" translatable="yes">gtk-about</property>
|
<property name="label">gtk-about</property>
|
||||||
<property name="use_underline">True</property>
|
|
||||||
<property name="use_stock">True</property>
|
<property name="use_stock">True</property>
|
||||||
</widget>
|
</widget>
|
||||||
</child>
|
</child>
|
||||||
|
|
@ -134,42 +163,62 @@
|
||||||
</child>
|
</child>
|
||||||
</widget>
|
</widget>
|
||||||
<packing>
|
<packing>
|
||||||
|
<property name="padding">0</property>
|
||||||
<property name="expand">False</property>
|
<property name="expand">False</property>
|
||||||
|
<property name="fill">True</property>
|
||||||
</packing>
|
</packing>
|
||||||
</child>
|
</child>
|
||||||
|
|
||||||
<child>
|
<child>
|
||||||
<widget class="GtkScrolledWindow" id="scrolledwindow">
|
<widget class="GtkScrolledWindow" id="scrolledwindow">
|
||||||
|
<property name="border_width">1</property>
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">True</property>
|
<property name="can_focus">True</property>
|
||||||
<property name="extension_events">GDK_EXTENSION_EVENTS_ALL</property>
|
|
||||||
<property name="border_width">1</property>
|
|
||||||
<property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
|
<property name="hscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
|
||||||
<property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
|
<property name="vscrollbar_policy">GTK_POLICY_AUTOMATIC</property>
|
||||||
<property name="shadow_type">GTK_SHADOW_ETCHED_IN</property>
|
<property name="shadow_type">GTK_SHADOW_ETCHED_IN</property>
|
||||||
|
<property name="window_placement">GTK_CORNER_TOP_LEFT</property>
|
||||||
|
|
||||||
<child>
|
<child>
|
||||||
<widget class="GtkTextView" id="textview">
|
<widget class="GtkTextView" id="textview">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="can_focus">True</property>
|
<property name="can_focus">True</property>
|
||||||
|
<property name="editable">True</property>
|
||||||
|
<property name="overwrite">False</property>
|
||||||
|
<property name="accepts_tab">True</property>
|
||||||
|
<property name="justification">GTK_JUSTIFY_LEFT</property>
|
||||||
|
<property name="wrap_mode">GTK_WRAP_NONE</property>
|
||||||
|
<property name="cursor_visible">True</property>
|
||||||
|
<property name="pixels_above_lines">0</property>
|
||||||
|
<property name="pixels_below_lines">0</property>
|
||||||
|
<property name="pixels_inside_wrap">0</property>
|
||||||
<property name="left_margin">2</property>
|
<property name="left_margin">2</property>
|
||||||
<property name="right_margin">2</property>
|
<property name="right_margin">2</property>
|
||||||
|
<property name="indent">0</property>
|
||||||
|
<property name="text" translatable="yes"></property>
|
||||||
</widget>
|
</widget>
|
||||||
</child>
|
</child>
|
||||||
</widget>
|
</widget>
|
||||||
<packing>
|
<packing>
|
||||||
<property name="position">1</property>
|
<property name="padding">0</property>
|
||||||
|
<property name="expand">True</property>
|
||||||
|
<property name="fill">True</property>
|
||||||
</packing>
|
</packing>
|
||||||
</child>
|
</child>
|
||||||
|
|
||||||
<child>
|
<child>
|
||||||
<widget class="GtkStatusbar" id="statusbar">
|
<widget class="GtkStatusbar" id="statusbar">
|
||||||
<property name="visible">True</property>
|
<property name="visible">True</property>
|
||||||
<property name="spacing">2</property>
|
<property name="has_resize_grip">True</property>
|
||||||
</widget>
|
</widget>
|
||||||
<packing>
|
<packing>
|
||||||
|
<property name="padding">0</property>
|
||||||
<property name="expand">False</property>
|
<property name="expand">False</property>
|
||||||
<property name="position">2</property>
|
<property name="fill">True</property>
|
||||||
</packing>
|
</packing>
|
||||||
</child>
|
</child>
|
||||||
</widget>
|
</widget>
|
||||||
</child>
|
</child>
|
||||||
</widget>
|
</widget>
|
||||||
|
|
||||||
</glade-interface>
|
</glade-interface>
|
||||||
|
|
|
||||||
67
install.txt
67
install.txt
|
|
@ -1,38 +1,17 @@
|
||||||
Installation
|
Installation
|
||||||
============
|
============
|
||||||
|
|
||||||
Installation on Windows - the easy way
|
|
||||||
--------------------------------------
|
|
||||||
|
|
||||||
Install Nimrod by downloading the appropriate .zip file and extracting it to a
|
Installation on Linux/UNIX
|
||||||
directory of your choice. The Nimrod Compiler will stay in this directory;
|
--------------------------
|
||||||
do not use a temporary one! You should add the ``bin`` directory of Nimrod to
|
|
||||||
your ``$PATH`` environment variable.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Installation on UNIX
|
|
||||||
--------------------
|
|
||||||
|
|
||||||
Note:
|
Note:
|
||||||
A C compiler is required - knowledge of C is not!
|
A C compiler is required - knowledge of C is not!
|
||||||
|
|
||||||
**Note: Installation under UNIX does not work yet** - you have to bootstrap.
|
|
||||||
Play with the ``koch.py`` script to compile the compiler. Under Windows the
|
|
||||||
``nim.exe`` is provided, so you don't need to do anything. Under UNIX you need
|
|
||||||
to install the `FreePascal <www.freepascal.org>`_ compiler.
|
|
||||||
Compile the compiler::
|
|
||||||
|
|
||||||
python koch.py nim
|
|
||||||
|
|
||||||
To bootstrap (does not work yet)::
|
|
||||||
|
|
||||||
python koch.py boot
|
|
||||||
|
|
||||||
The GNU C Compiler is fully supported, other compilers may work. The C compiler
|
The GNU C Compiler is fully supported, other compilers may work. The C compiler
|
||||||
should be in your ``$PATH`` (most likely the case). Note that some Linux
|
should be in your ``$PATH`` (most likely the case). Note that some Linux
|
||||||
distributions do not ship with a C compiler preinstalled - then you have to
|
distributions do not ship with a GCC compiler preinstalled - then you have to
|
||||||
install one.
|
install it.
|
||||||
|
|
||||||
After you have made sure that a C compiler is available, install Nimrod
|
After you have made sure that a C compiler is available, install Nimrod
|
||||||
by downloading the appropriate ``.zip`` file and extracting it to a
|
by downloading the appropriate ``.zip`` file and extracting it to a
|
||||||
|
|
@ -46,7 +25,7 @@ Then run the following command::
|
||||||
Unlike other software, Nimrod does not distribute its files over the whole file
|
Unlike other software, Nimrod does not distribute its files over the whole file
|
||||||
hierarchy. This has the advantage that you can deinstall it by just deleting
|
hierarchy. This has the advantage that you can deinstall it by just deleting
|
||||||
its folder. The disadvantage is that you have to add it to your ``PATH``
|
its folder. The disadvantage is that you have to add it to your ``PATH``
|
||||||
manually. The alternative is to create a symbolic link in ``/usr/bin``::
|
manually. An alternative is to create a symbolic link in ``/usr/bin``::
|
||||||
|
|
||||||
[sudo] ln -s $your_install_dir/bin/nimrod /usr/bin/nimrod
|
[sudo] ln -s $your_install_dir/bin/nimrod /usr/bin/nimrod
|
||||||
|
|
||||||
|
|
@ -55,35 +34,43 @@ Installation on the Macintosh
|
||||||
-----------------------------
|
-----------------------------
|
||||||
|
|
||||||
Only MacOS X is supported.
|
Only MacOS X is supported.
|
||||||
Since MacOS X is UNIX based too, it works like the installation on UNIX. You
|
Since MacOS X is UNIX based too, it works like the installation on Linux. You
|
||||||
need to install Apple's developer's tools for the GNU Compiler Collection
|
need to install Apple's developer's tools for the GNU Compiler Collection
|
||||||
though.
|
though.
|
||||||
|
|
||||||
|
|
||||||
|
Installation on Windows - the easy way
|
||||||
|
--------------------------------------
|
||||||
|
|
||||||
|
Install Nimrod by downloading and running
|
||||||
|
the ``nimrod_windows_$version.exe`` file. The installation procedure detects
|
||||||
|
which C compilers are installed and writes the ``config/nimrod.cfg`` file
|
||||||
|
for you. If no installed C compiler is found, the ``LLVM-GCC`` compiler is
|
||||||
|
used that is bundled with this installer. So it should just work.
|
||||||
|
|
||||||
|
|
||||||
Installation on Windows - the hard way
|
Installation on Windows - the hard way
|
||||||
--------------------------------------
|
--------------------------------------
|
||||||
|
|
||||||
Windows does not ship with a C compiler; you have to install one. The
|
Windows does not ship with a C compiler; you have to install one. The
|
||||||
following C compilers are supported under Windows:
|
following C compilers are supported under Windows:
|
||||||
|
|
||||||
- | Digital Mars C++
|
|
||||||
| http://www.digitalmars.com/download/freecompiler.html
|
|
||||||
- | Watcom C++
|
|
||||||
| http://www.openwatcom.org/ftp/
|
|
||||||
- | Borland C++ (5.5 or above; including Borland C++Builder)
|
|
||||||
| http://www.borland.com/downloads/download_cbuilder.html
|
|
||||||
| (Download the package under "compiler" - this requires registration though.)
|
|
||||||
- | Microsoft's Visual C++
|
- | Microsoft's Visual C++
|
||||||
| http://msdn.microsoft.com/visualc
|
| http://msdn.microsoft.com/visualc
|
||||||
| (You may need the SDK too - but not the full one: Essential are only
|
| (You may need the SDK too - but not the full one: Essential are only
|
||||||
the win32api header files and import libraries.)
|
the win32api header files and import libraries.)
|
||||||
|
- | Borland C++ (5.5 or above; including Borland C++Builder)
|
||||||
|
| http://www.borland.com/downloads/download_cbuilder.html
|
||||||
|
| (Download the package under "compiler" - this requires registration though.)
|
||||||
- | Gnu C Compiler (the mingw version; the cygwin version has not been tested!)
|
- | Gnu C Compiler (the mingw version; the cygwin version has not been tested!)
|
||||||
| http://www.mingw.org/download.shtml
|
| http://www.mingw.org/download.shtml
|
||||||
- | LLVM with GNU C/C++ frontend
|
- | LLVM with GNU C/C++ frontend
|
||||||
| http://llvm.org/releases/download.html#2.2
|
| http://llvm.org/releases/download.html#2.2
|
||||||
- | Pelles C Compiler
|
- | Digital Mars C++
|
||||||
|
| http://www.digitalmars.com/download/freecompiler.html
|
||||||
|
- | Pelles C Compiler (bootstrapping does not work with PCC!)
|
||||||
| http://www.smorgasbordet.com/pellesc
|
| http://www.smorgasbordet.com/pellesc
|
||||||
- | Lcc-win32
|
- | Lcc-win32 (bootstrapping does not work with LCC!)
|
||||||
| http://www.cs.virginia.edu/~lcc-win32
|
| http://www.cs.virginia.edu/~lcc-win32
|
||||||
|
|
||||||
All of the above compilers are available for free!
|
All of the above compilers are available for free!
|
||||||
|
|
@ -96,10 +83,4 @@ After you have made sure that a C compiler is available, install
|
||||||
Nimrod by downloading the appropriate .zip file and extracting it to a
|
Nimrod by downloading the appropriate .zip file and extracting it to a
|
||||||
directory of your choice. The Nimrod Compiler will stay in this
|
directory of your choice. The Nimrod Compiler will stay in this
|
||||||
directory; do not use a temporary one! Then adapt the ``config/nimrod.cfg``
|
directory; do not use a temporary one! Then adapt the ``config/nimrod.cfg``
|
||||||
file appropriately. Choose your C compiler and press ``OK``. You should
|
file appropriately. You should add Nimrod to your ``$PATH``.
|
||||||
add Nimrod to your ``$PATH``.
|
|
||||||
|
|
||||||
Alternatively, you can install Nimrod with the ``koch.py`` script just like
|
|
||||||
in the UNIX installation instructions.
|
|
||||||
|
|
||||||
Nimrod does not use the Registry and can be removed by just deleting its folder.
|
|
||||||
|
|
|
||||||
24
kochmod.py
24
kochmod.py
|
|
@ -2,7 +2,7 @@
|
||||||
# For further documentation see koch.txt or koch.html.
|
# For further documentation see koch.txt or koch.html.
|
||||||
# (c) 2007 Andreas Rumpf
|
# (c) 2007 Andreas Rumpf
|
||||||
|
|
||||||
VERSION = "1.0.3"
|
VERSION = "1.0.4"
|
||||||
|
|
||||||
import os, os.path, inspect, re, shutil, glob, cPickle, zlib, string, \
|
import os, os.path, inspect, re, shutil, glob, cPickle, zlib, string, \
|
||||||
getopt, sys
|
getopt, sys
|
||||||
|
|
@ -18,6 +18,25 @@ _FINGERPRINTS_FILE = "koch.dat"
|
||||||
# has changed. This works reliably, which cannot be said from just taking
|
# has changed. This works reliably, which cannot be said from just taking
|
||||||
# filetime-stamps.
|
# filetime-stamps.
|
||||||
|
|
||||||
|
# -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
def FileCmp(filenameA, filenameB):
|
||||||
|
SIZE = 4096*2
|
||||||
|
result = True
|
||||||
|
a = file(filenameA, "rb")
|
||||||
|
b = file(filenameB, "rb")
|
||||||
|
while True:
|
||||||
|
x = a.read(SIZE)
|
||||||
|
y = b.read(SIZE)
|
||||||
|
if x != y:
|
||||||
|
result = False
|
||||||
|
break
|
||||||
|
elif len(x) < SIZE: # EOF?
|
||||||
|
break
|
||||||
|
a.close()
|
||||||
|
b.close()
|
||||||
|
return result
|
||||||
|
|
||||||
# ---------------- C Compilers ------------------------------------------------
|
# ---------------- C Compilers ------------------------------------------------
|
||||||
|
|
||||||
# We support the following C compilers:
|
# We support the following C compilers:
|
||||||
|
|
@ -185,6 +204,9 @@ def Subs(frmt, **substitution):
|
||||||
else:
|
else:
|
||||||
return tuple([string.Template(x).substitute(substitution) for x in frmt])
|
return tuple([string.Template(x).substitute(substitution) for x in frmt])
|
||||||
|
|
||||||
|
def SafeSubs(frmt, **substitution):
|
||||||
|
return string.Template(frmt).safe_substitute(substitution)
|
||||||
|
|
||||||
_baseDir = os.getcwd()
|
_baseDir = os.getcwd()
|
||||||
BaseDir = _baseDir
|
BaseDir = _baseDir
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -17,9 +17,9 @@ proc c_memcpy(a, b: CString, size: cint) {.nodecl, importc: "memcpy".}
|
||||||
proc c_strlen(a: CString): cint {.nodecl, importc: "strlen".}
|
proc c_strlen(a: CString): cint {.nodecl, importc: "strlen".}
|
||||||
|
|
||||||
type
|
type
|
||||||
C_TextFile {.importc: "FILE", nodecl.} = record # empty record for
|
C_TextFile {.importc: "FILE", nodecl, final.} = object # empty record for
|
||||||
# data hiding
|
# data hiding
|
||||||
C_BinaryFile {.importc: "FILE", nodecl.} = record
|
C_BinaryFile {.importc: "FILE", nodecl, final.} = object
|
||||||
C_TextFileStar = ptr CTextFile
|
C_TextFileStar = ptr CTextFile
|
||||||
C_BinaryFileStar = ptr CBinaryFile
|
C_BinaryFileStar = ptr CBinaryFile
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -18,13 +18,13 @@ proc raiseDivByZero {.exportc: "raiseDivByZero".} =
|
||||||
raise newException(EDivByZero, "divison by zero")
|
raise newException(EDivByZero, "divison by zero")
|
||||||
|
|
||||||
proc addInt64(a, b: int64): int64 {.compilerProc, inline.} =
|
proc addInt64(a, b: int64): int64 {.compilerProc, inline.} =
|
||||||
result = a + b
|
result = a +% b
|
||||||
if (result xor a) >= int64(0) or (result xor b) >= int64(0):
|
if (result xor a) >= int64(0) or (result xor b) >= int64(0):
|
||||||
return result
|
return result
|
||||||
raiseOverflow()
|
raiseOverflow()
|
||||||
|
|
||||||
proc subInt64(a, b: int64): int64 {.compilerProc, inline.} =
|
proc subInt64(a, b: int64): int64 {.compilerProc, inline.} =
|
||||||
result = a - b
|
result = a -% b
|
||||||
if (result xor a) >= int64(0) or (result xor not b) >= int64(0):
|
if (result xor a) >= int64(0) or (result xor not b) >= int64(0):
|
||||||
return result
|
return result
|
||||||
raiseOverflow()
|
raiseOverflow()
|
||||||
|
|
@ -74,7 +74,7 @@ proc modInt64(a, b: int64): int64 {.compilerProc, inline.} =
|
||||||
proc mulInt64(a, b: int64): int64 {.compilerproc.} =
|
proc mulInt64(a, b: int64): int64 {.compilerproc.} =
|
||||||
var
|
var
|
||||||
resAsFloat, floatProd: float64
|
resAsFloat, floatProd: float64
|
||||||
result = a * b
|
result = a *% b
|
||||||
floatProd = float64(a) # conversion
|
floatProd = float64(a) # conversion
|
||||||
floatProd = floatProd * float64(b)
|
floatProd = floatProd * float64(b)
|
||||||
resAsFloat = float64(result)
|
resAsFloat = float64(result)
|
||||||
|
|
@ -276,13 +276,13 @@ else:
|
||||||
# Platform independant versions of the above (slower!)
|
# Platform independant versions of the above (slower!)
|
||||||
|
|
||||||
proc addInt(a, b: int): int =
|
proc addInt(a, b: int): int =
|
||||||
result = a + b
|
result = a +% b
|
||||||
if (result xor a) >= 0 or (result xor b) >= 0:
|
if (result xor a) >= 0 or (result xor b) >= 0:
|
||||||
return result
|
return result
|
||||||
raiseOverflow()
|
raiseOverflow()
|
||||||
|
|
||||||
proc subInt(a, b: int): int =
|
proc subInt(a, b: int): int =
|
||||||
result = a - b
|
result = a -% b
|
||||||
if (result xor a) >= 0 or (result xor not b) >= 0:
|
if (result xor a) >= 0 or (result xor not b) >= 0:
|
||||||
return result
|
return result
|
||||||
raiseOverflow()
|
raiseOverflow()
|
||||||
|
|
@ -327,7 +327,7 @@ else:
|
||||||
var
|
var
|
||||||
resAsFloat, floatProd: float
|
resAsFloat, floatProd: float
|
||||||
|
|
||||||
result = a * b
|
result = a *% b
|
||||||
floatProd = toFloat(a) * toFloat(b)
|
floatProd = toFloat(a) * toFloat(b)
|
||||||
resAsFloat = toFloat(result)
|
resAsFloat = toFloat(result)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -55,7 +55,8 @@ proc genericAssign(dest, src: Pointer, mt: PNimType) =
|
||||||
var dstseq = cast[PGenericSeq](dst)
|
var dstseq = cast[PGenericSeq](dst)
|
||||||
dstseq.len = seq.len
|
dstseq.len = seq.len
|
||||||
dstseq.space = seq.len
|
dstseq.space = seq.len
|
||||||
of tyRecord, tyObject, tyTuple:
|
of tyObject, tyTuple, tyPureObject:
|
||||||
|
# we don't need to copy m_type field for tyObject, as they are equal anyway
|
||||||
genericAssignAux(dest, src, mt.node)
|
genericAssignAux(dest, src, mt.node)
|
||||||
of tyArray, tyArrayConstr:
|
of tyArray, tyArrayConstr:
|
||||||
for i in 0..(mt.size div mt.base.size)-1:
|
for i in 0..(mt.size div mt.base.size)-1:
|
||||||
|
|
@ -75,6 +76,7 @@ proc genericAssign(dest, src: Pointer, mt: PNimType) =
|
||||||
copyMem(dest, src, mt.size) # copy raw bits
|
copyMem(dest, src, mt.size) # copy raw bits
|
||||||
|
|
||||||
proc genericSeqAssign(dest, src: Pointer, mt: PNimType) {.compilerProc.} =
|
proc genericSeqAssign(dest, src: Pointer, mt: PNimType) {.compilerProc.} =
|
||||||
|
var src = src # ugly, but I like to stress the parser sometimes :-)
|
||||||
genericAssign(dest, addr(src), mt)
|
genericAssign(dest, addr(src), mt)
|
||||||
|
|
||||||
proc genericAssignOpenArray(dest, src: pointer, len: int,
|
proc genericAssignOpenArray(dest, src: pointer, len: int,
|
||||||
|
|
@ -110,7 +112,7 @@ proc objectInit(dest: Pointer, typ: PNimType) =
|
||||||
var pint = cast[ptr PNimType](dest)
|
var pint = cast[ptr PNimType](dest)
|
||||||
pint^ = typ
|
pint^ = typ
|
||||||
objectInitAux(dest, typ.node)
|
objectInitAux(dest, typ.node)
|
||||||
of tyRecord:
|
of tyTuple, tyPureObject:
|
||||||
objectInitAux(dest, typ.node)
|
objectInitAux(dest, typ.node)
|
||||||
of tyArray, tyArrayConstr:
|
of tyArray, tyArrayConstr:
|
||||||
for i in 0..(typ.size div typ.base.size)-1:
|
for i in 0..(typ.size div typ.base.size)-1:
|
||||||
|
|
|
||||||
|
|
@ -149,13 +149,13 @@ type
|
||||||
cdecl.}
|
cdecl.}
|
||||||
cairo_read_func_t* = proc (closure: Pointer, data: PByte, len: int32): cairo_status_t{.
|
cairo_read_func_t* = proc (closure: Pointer, data: PByte, len: int32): cairo_status_t{.
|
||||||
cdecl.}
|
cdecl.}
|
||||||
cairo_t* = record #OPAQUE
|
cairo_t* {.final.} = object #OPAQUE
|
||||||
cairo_surface_t* = record #OPAQUE
|
cairo_surface_t* {.final.} = object #OPAQUE
|
||||||
cairo_pattern_t* = record #OPAQUE
|
cairo_pattern_t* {.final.} = object #OPAQUE
|
||||||
cairo_scaled_font_t* = record #OPAQUE
|
cairo_scaled_font_t* {.final.} = object #OPAQUE
|
||||||
cairo_font_face_t* = record #OPAQUE
|
cairo_font_face_t* {.final.} = object #OPAQUE
|
||||||
cairo_font_options_t* = record #OPAQUE
|
cairo_font_options_t* {.final.} = object #OPAQUE
|
||||||
cairo_matrix_t* = record
|
cairo_matrix_t* {.final.} = object
|
||||||
xx: float64
|
xx: float64
|
||||||
yx: float64
|
yx: float64
|
||||||
xy: float64
|
xy: float64
|
||||||
|
|
@ -163,15 +163,15 @@ type
|
||||||
x0: float64
|
x0: float64
|
||||||
y0: float64
|
y0: float64
|
||||||
|
|
||||||
cairo_user_data_key_t* = record
|
cairo_user_data_key_t* {.final.} = object
|
||||||
unused: int32
|
unused: int32
|
||||||
|
|
||||||
cairo_glyph_t* = record
|
cairo_glyph_t* {.final.} = object
|
||||||
index: int32
|
index: int32
|
||||||
x: float64
|
x: float64
|
||||||
y: float64
|
y: float64
|
||||||
|
|
||||||
cairo_text_extents_t* = record
|
cairo_text_extents_t* {.final.} = object
|
||||||
x_bearing: float64
|
x_bearing: float64
|
||||||
y_bearing: float64
|
y_bearing: float64
|
||||||
width: float64
|
width: float64
|
||||||
|
|
@ -179,28 +179,28 @@ type
|
||||||
x_advance: float64
|
x_advance: float64
|
||||||
y_advance: float64
|
y_advance: float64
|
||||||
|
|
||||||
cairo_font_extents_t* = record
|
cairo_font_extents_t* {.final.} = object
|
||||||
ascent: float64
|
ascent: float64
|
||||||
descent: float64
|
descent: float64
|
||||||
height: float64
|
height: float64
|
||||||
max_x_advance: float64
|
max_x_advance: float64
|
||||||
max_y_advance: float64
|
max_y_advance: float64
|
||||||
|
|
||||||
cairo_path_data_t* = record #* _type : cairo_path_data_type_t;
|
cairo_path_data_t* {.final.} = object #* _type : cairo_path_data_type_t;
|
||||||
# length : LongInt;
|
# length : LongInt;
|
||||||
# end
|
# end
|
||||||
x: float64
|
x: float64
|
||||||
y: float64
|
y: float64
|
||||||
|
|
||||||
cairo_path_t* = record
|
cairo_path_t* {.final.} = object
|
||||||
status: cairo_status_t
|
status: cairo_status_t
|
||||||
data: Pcairo_path_data_t
|
data: Pcairo_path_data_t
|
||||||
num_data: int32
|
num_data: int32
|
||||||
|
|
||||||
cairo_rectangle_t* = record
|
cairo_rectangle_t* {.final.} = object
|
||||||
x, y, width, height: float64
|
x, y, width, height: float64
|
||||||
|
|
||||||
cairo_rectangle_list_t* = record
|
cairo_rectangle_list_t* {.final.} = object
|
||||||
status: cairo_status_t
|
status: cairo_status_t
|
||||||
rectangles: Pcairo_rectangle_t
|
rectangles: Pcairo_rectangle_t
|
||||||
num_rectangles: int32
|
num_rectangles: int32
|
||||||
|
|
|
||||||
|
|
@ -56,7 +56,7 @@ type
|
||||||
ATK_LAYER_INVALID, ATK_LAYER_BACKGROUND, ATK_LAYER_CANVAS, ATK_LAYER_WIDGET,
|
ATK_LAYER_INVALID, ATK_LAYER_BACKGROUND, ATK_LAYER_CANVAS, ATK_LAYER_WIDGET,
|
||||||
ATK_LAYER_MDI, ATK_LAYER_POPUP, ATK_LAYER_OVERLAY
|
ATK_LAYER_MDI, ATK_LAYER_POPUP, ATK_LAYER_OVERLAY
|
||||||
PAtkPropertyValues* = ptr TAtkPropertyValues
|
PAtkPropertyValues* = ptr TAtkPropertyValues
|
||||||
TAtkPropertyValues* = record
|
TAtkPropertyValues* {.final.} = object
|
||||||
property_name*: cstring
|
property_name*: cstring
|
||||||
old_value*: TGValue
|
old_value*: TGValue
|
||||||
new_value*: TGValue
|
new_value*: TGValue
|
||||||
|
|
@ -379,7 +379,7 @@ type
|
||||||
|
|
||||||
TAtkAttributeSet* = TGSList
|
TAtkAttributeSet* = TGSList
|
||||||
PAtkAttribute* = ptr TAtkAttribute
|
PAtkAttribute* = ptr TAtkAttribute
|
||||||
TAtkAttribute* = record
|
TAtkAttribute* {.final.} = object
|
||||||
name*: cstring
|
name*: cstring
|
||||||
value*: cstring
|
value*: cstring
|
||||||
|
|
||||||
|
|
@ -453,7 +453,7 @@ type
|
||||||
TAtkEventListenerInitProc* = proc ()
|
TAtkEventListenerInitProc* = proc ()
|
||||||
TAtkEventListenerInit* = proc (para1: TAtkEventListenerInitProc){.cdecl.}
|
TAtkEventListenerInit* = proc (para1: TAtkEventListenerInitProc){.cdecl.}
|
||||||
PAtkKeyEventStruct* = ptr TAtkKeyEventStruct
|
PAtkKeyEventStruct* = ptr TAtkKeyEventStruct
|
||||||
TAtkKeyEventStruct* = record
|
TAtkKeyEventStruct* {.final.} = object
|
||||||
`type`*: gint
|
`type`*: gint
|
||||||
state*: guint
|
state*: guint
|
||||||
keyval*: guint
|
keyval*: guint
|
||||||
|
|
|
||||||
|
|
@ -32,7 +32,7 @@ type
|
||||||
TGdkVisualClass* = object of TGObjectClass
|
TGdkVisualClass* = object of TGObjectClass
|
||||||
|
|
||||||
PGdkColor* = ptr TGdkColor
|
PGdkColor* = ptr TGdkColor
|
||||||
TGdkColor* = record
|
TGdkColor* {.final.} = object
|
||||||
pixel*: guint32
|
pixel*: guint32
|
||||||
red*: guint16
|
red*: guint16
|
||||||
green*: guint16
|
green*: guint16
|
||||||
|
|
@ -52,7 +52,7 @@ type
|
||||||
TGdkFontType* = enum
|
TGdkFontType* = enum
|
||||||
GDK_FONT_FONT, GDK_FONT_FONTSET
|
GDK_FONT_FONT, GDK_FONT_FONTSET
|
||||||
PGdkFont* = ptr TGdkFont
|
PGdkFont* = ptr TGdkFont
|
||||||
TGdkFont* = record
|
TGdkFont* {.final.} = object
|
||||||
`type`*: TGdkFontType
|
`type`*: TGdkFontType
|
||||||
ascent*: gint
|
ascent*: gint
|
||||||
descent*: gint
|
descent*: gint
|
||||||
|
|
@ -79,7 +79,7 @@ type
|
||||||
PGdkGCValuesMask* = ptr TGdkGCValuesMask
|
PGdkGCValuesMask* = ptr TGdkGCValuesMask
|
||||||
TGdkGCValuesMask* = int32
|
TGdkGCValuesMask* = int32
|
||||||
PGdkGCValues* = ptr TGdkGCValues
|
PGdkGCValues* = ptr TGdkGCValues
|
||||||
TGdkGCValues* = record
|
TGdkGCValues* {.final.} = object
|
||||||
foreground*: TGdkColor
|
foreground*: TGdkColor
|
||||||
background*: TGdkColor
|
background*: TGdkColor
|
||||||
font*: PGdkFont
|
font*: PGdkFont
|
||||||
|
|
@ -125,7 +125,7 @@ type
|
||||||
TGdkInputCondition* = int32
|
TGdkInputCondition* = int32
|
||||||
PGdkStatus* = ptr TGdkStatus
|
PGdkStatus* = ptr TGdkStatus
|
||||||
TGdkStatus* = int32
|
TGdkStatus* = int32
|
||||||
TGdkPoint* = record
|
TGdkPoint* {.final.} = object
|
||||||
x*: gint
|
x*: gint
|
||||||
y*: gint
|
y*: gint
|
||||||
|
|
||||||
|
|
@ -135,14 +135,14 @@ type
|
||||||
PGdkWChar* = ptr TGdkWChar
|
PGdkWChar* = ptr TGdkWChar
|
||||||
TGdkWChar* = guint32
|
TGdkWChar* = guint32
|
||||||
PGdkSegment* = ptr TGdkSegment
|
PGdkSegment* = ptr TGdkSegment
|
||||||
TGdkSegment* = record
|
TGdkSegment* {.final.} = object
|
||||||
x1*: gint
|
x1*: gint
|
||||||
y1*: gint
|
y1*: gint
|
||||||
x2*: gint
|
x2*: gint
|
||||||
y2*: gint
|
y2*: gint
|
||||||
|
|
||||||
PGdkRectangle* = ptr TGdkRectangle
|
PGdkRectangle* = ptr TGdkRectangle
|
||||||
TGdkRectangle* = record
|
TGdkRectangle* {.final.} = object
|
||||||
x*: gint
|
x*: gint
|
||||||
y*: gint
|
y*: gint
|
||||||
width*: gint
|
width*: gint
|
||||||
|
|
@ -190,7 +190,7 @@ type
|
||||||
PGdkCursorType* = ptr TGdkCursorType
|
PGdkCursorType* = ptr TGdkCursorType
|
||||||
TGdkCursorType* = gint
|
TGdkCursorType* = gint
|
||||||
PGdkCursor* = ptr TGdkCursor
|
PGdkCursor* = ptr TGdkCursor
|
||||||
TGdkCursor* = record
|
TGdkCursor* {.final.} = object
|
||||||
`type`*: TGdkCursorType
|
`type`*: TGdkCursorType
|
||||||
ref_count*: guint
|
ref_count*: guint
|
||||||
|
|
||||||
|
|
@ -220,14 +220,14 @@ type
|
||||||
PGdkRegionBox* = ptr TGdkRegionBox
|
PGdkRegionBox* = ptr TGdkRegionBox
|
||||||
TGdkRegionBox* = TGdkSegment
|
TGdkRegionBox* = TGdkSegment
|
||||||
PGdkRegion* = ptr TGdkRegion
|
PGdkRegion* = ptr TGdkRegion
|
||||||
TGdkRegion* = record
|
TGdkRegion* {.final.} = object
|
||||||
size*: int32
|
size*: int32
|
||||||
numRects*: int32
|
numRects*: int32
|
||||||
rects*: PGdkRegionBox
|
rects*: PGdkRegionBox
|
||||||
extents*: TGdkRegionBox
|
extents*: TGdkRegionBox
|
||||||
|
|
||||||
PPOINTBLOCK* = ptr TPOINTBLOCK
|
PPOINTBLOCK* = ptr TPOINTBLOCK
|
||||||
TPOINTBLOCK* = record
|
TPOINTBLOCK* {.final.} = object
|
||||||
pts*: array[0..(NUMPTSTOBUFFER) - 1, TGdkPoint]
|
pts*: array[0..(NUMPTSTOBUFFER) - 1, TGdkPoint]
|
||||||
next*: PPOINTBLOCK
|
next*: PPOINTBLOCK
|
||||||
|
|
||||||
|
|
@ -336,13 +336,13 @@ type
|
||||||
GDK_SETTING_ACTION_NEW, GDK_SETTING_ACTION_CHANGED,
|
GDK_SETTING_ACTION_NEW, GDK_SETTING_ACTION_CHANGED,
|
||||||
GDK_SETTING_ACTION_DELETED
|
GDK_SETTING_ACTION_DELETED
|
||||||
PGdkEventAny* = ptr TGdkEventAny
|
PGdkEventAny* = ptr TGdkEventAny
|
||||||
TGdkEventAny* = record
|
TGdkEventAny* {.final.} = object
|
||||||
`type`*: TGdkEventType
|
`type`*: TGdkEventType
|
||||||
window*: PGdkWindow
|
window*: PGdkWindow
|
||||||
send_event*: gint8
|
send_event*: gint8
|
||||||
|
|
||||||
PGdkEventExpose* = ptr TGdkEventExpose
|
PGdkEventExpose* = ptr TGdkEventExpose
|
||||||
TGdkEventExpose* = record
|
TGdkEventExpose* {.final.} = object
|
||||||
`type`*: TGdkEventType
|
`type`*: TGdkEventType
|
||||||
window*: PGdkWindow
|
window*: PGdkWindow
|
||||||
send_event*: gint8
|
send_event*: gint8
|
||||||
|
|
@ -351,20 +351,20 @@ type
|
||||||
count*: gint
|
count*: gint
|
||||||
|
|
||||||
PGdkEventNoExpose* = ptr TGdkEventNoExpose
|
PGdkEventNoExpose* = ptr TGdkEventNoExpose
|
||||||
TGdkEventNoExpose* = record
|
TGdkEventNoExpose* {.final.} = object
|
||||||
`type`*: TGdkEventType
|
`type`*: TGdkEventType
|
||||||
window*: PGdkWindow
|
window*: PGdkWindow
|
||||||
send_event*: gint8
|
send_event*: gint8
|
||||||
|
|
||||||
PGdkEventVisibility* = ptr TGdkEventVisibility
|
PGdkEventVisibility* = ptr TGdkEventVisibility
|
||||||
TGdkEventVisibility* = record
|
TGdkEventVisibility* {.final.} = object
|
||||||
`type`*: TGdkEventType
|
`type`*: TGdkEventType
|
||||||
window*: PGdkWindow
|
window*: PGdkWindow
|
||||||
send_event*: gint8
|
send_event*: gint8
|
||||||
state*: TGdkVisibilityState
|
state*: TGdkVisibilityState
|
||||||
|
|
||||||
PGdkEventMotion* = ptr TGdkEventMotion
|
PGdkEventMotion* = ptr TGdkEventMotion
|
||||||
TGdkEventMotion* = record
|
TGdkEventMotion* {.final.} = object
|
||||||
`type`*: TGdkEventType
|
`type`*: TGdkEventType
|
||||||
window*: PGdkWindow
|
window*: PGdkWindow
|
||||||
send_event*: gint8
|
send_event*: gint8
|
||||||
|
|
@ -379,7 +379,7 @@ type
|
||||||
y_root*: gdouble
|
y_root*: gdouble
|
||||||
|
|
||||||
PGdkEventButton* = ptr TGdkEventButton
|
PGdkEventButton* = ptr TGdkEventButton
|
||||||
TGdkEventButton* = record
|
TGdkEventButton* {.final.} = object
|
||||||
`type`*: TGdkEventType
|
`type`*: TGdkEventType
|
||||||
window*: PGdkWindow
|
window*: PGdkWindow
|
||||||
send_event*: gint8
|
send_event*: gint8
|
||||||
|
|
@ -394,7 +394,7 @@ type
|
||||||
y_root*: gdouble
|
y_root*: gdouble
|
||||||
|
|
||||||
PGdkEventScroll* = ptr TGdkEventScroll
|
PGdkEventScroll* = ptr TGdkEventScroll
|
||||||
TGdkEventScroll* = record
|
TGdkEventScroll* {.final.} = object
|
||||||
`type`*: TGdkEventType
|
`type`*: TGdkEventType
|
||||||
window*: PGdkWindow
|
window*: PGdkWindow
|
||||||
send_event*: gint8
|
send_event*: gint8
|
||||||
|
|
@ -408,7 +408,7 @@ type
|
||||||
y_root*: gdouble
|
y_root*: gdouble
|
||||||
|
|
||||||
PGdkEventKey* = ptr TGdkEventKey
|
PGdkEventKey* = ptr TGdkEventKey
|
||||||
TGdkEventKey* = record
|
TGdkEventKey* {.final.} = object
|
||||||
`type`*: TGdkEventType
|
`type`*: TGdkEventType
|
||||||
window*: PGdkWindow
|
window*: PGdkWindow
|
||||||
send_event*: gint8
|
send_event*: gint8
|
||||||
|
|
@ -421,7 +421,7 @@ type
|
||||||
group*: guint8
|
group*: guint8
|
||||||
|
|
||||||
PGdkEventCrossing* = ptr TGdkEventCrossing
|
PGdkEventCrossing* = ptr TGdkEventCrossing
|
||||||
TGdkEventCrossing* = record
|
TGdkEventCrossing* {.final.} = object
|
||||||
`type`*: TGdkEventType
|
`type`*: TGdkEventType
|
||||||
window*: PGdkWindow
|
window*: PGdkWindow
|
||||||
send_event*: gint8
|
send_event*: gint8
|
||||||
|
|
@ -437,14 +437,14 @@ type
|
||||||
state*: guint
|
state*: guint
|
||||||
|
|
||||||
PGdkEventFocus* = ptr TGdkEventFocus
|
PGdkEventFocus* = ptr TGdkEventFocus
|
||||||
TGdkEventFocus* = record
|
TGdkEventFocus* {.final.} = object
|
||||||
`type`*: TGdkEventType
|
`type`*: TGdkEventType
|
||||||
window*: PGdkWindow
|
window*: PGdkWindow
|
||||||
send_event*: gint8
|
send_event*: gint8
|
||||||
`in`*: gint16
|
`in`*: gint16
|
||||||
|
|
||||||
PGdkEventConfigure* = ptr TGdkEventConfigure
|
PGdkEventConfigure* = ptr TGdkEventConfigure
|
||||||
TGdkEventConfigure* = record
|
TGdkEventConfigure* {.final.} = object
|
||||||
`type`*: TGdkEventType
|
`type`*: TGdkEventType
|
||||||
window*: PGdkWindow
|
window*: PGdkWindow
|
||||||
send_event*: gint8
|
send_event*: gint8
|
||||||
|
|
@ -454,7 +454,7 @@ type
|
||||||
height*: gint
|
height*: gint
|
||||||
|
|
||||||
PGdkEventProperty* = ptr TGdkEventProperty
|
PGdkEventProperty* = ptr TGdkEventProperty
|
||||||
TGdkEventProperty* = record
|
TGdkEventProperty* {.final.} = object
|
||||||
`type`*: TGdkEventType
|
`type`*: TGdkEventType
|
||||||
window*: PGdkWindow
|
window*: PGdkWindow
|
||||||
send_event*: gint8
|
send_event*: gint8
|
||||||
|
|
@ -464,7 +464,7 @@ type
|
||||||
|
|
||||||
TGdkNativeWindow* = pointer
|
TGdkNativeWindow* = pointer
|
||||||
PGdkEventSelection* = ptr TGdkEventSelection
|
PGdkEventSelection* = ptr TGdkEventSelection
|
||||||
TGdkEventSelection* = record
|
TGdkEventSelection* {.final.} = object
|
||||||
`type`*: TGdkEventType
|
`type`*: TGdkEventType
|
||||||
window*: PGdkWindow
|
window*: PGdkWindow
|
||||||
send_event*: gint8
|
send_event*: gint8
|
||||||
|
|
@ -475,7 +475,7 @@ type
|
||||||
requestor*: TGdkNativeWindow
|
requestor*: TGdkNativeWindow
|
||||||
|
|
||||||
PGdkEventProximity* = ptr TGdkEventProximity
|
PGdkEventProximity* = ptr TGdkEventProximity
|
||||||
TGdkEventProximity* = record
|
TGdkEventProximity* {.final.} = object
|
||||||
`type`*: TGdkEventType
|
`type`*: TGdkEventType
|
||||||
window*: PGdkWindow
|
window*: PGdkWindow
|
||||||
send_event*: gint8
|
send_event*: gint8
|
||||||
|
|
@ -483,11 +483,11 @@ type
|
||||||
device*: PGdkDevice
|
device*: PGdkDevice
|
||||||
|
|
||||||
PmatDUMMY* = ptr TmatDUMMY
|
PmatDUMMY* = ptr TmatDUMMY
|
||||||
TmatDUMMY* = record
|
TmatDUMMY* {.final.} = object
|
||||||
b*: array[0..19, char]
|
b*: array[0..19, char]
|
||||||
|
|
||||||
PGdkEventClient* = ptr TGdkEventClient
|
PGdkEventClient* = ptr TGdkEventClient
|
||||||
TGdkEventClient* = record
|
TGdkEventClient* {.final.} = object
|
||||||
`type`*: TGdkEventType
|
`type`*: TGdkEventType
|
||||||
window*: PGdkWindow
|
window*: PGdkWindow
|
||||||
send_event*: gint8
|
send_event*: gint8
|
||||||
|
|
@ -496,7 +496,7 @@ type
|
||||||
b*: array[0..19, char]
|
b*: array[0..19, char]
|
||||||
|
|
||||||
PGdkEventSetting* = ptr TGdkEventSetting
|
PGdkEventSetting* = ptr TGdkEventSetting
|
||||||
TGdkEventSetting* = record
|
TGdkEventSetting* {.final.} = object
|
||||||
`type`*: TGdkEventType
|
`type`*: TGdkEventType
|
||||||
window*: PGdkWindow
|
window*: PGdkWindow
|
||||||
send_event*: gint8
|
send_event*: gint8
|
||||||
|
|
@ -504,7 +504,7 @@ type
|
||||||
name*: cstring
|
name*: cstring
|
||||||
|
|
||||||
PGdkEventWindowState* = ptr TGdkEventWindowState
|
PGdkEventWindowState* = ptr TGdkEventWindowState
|
||||||
TGdkEventWindowState* = record
|
TGdkEventWindowState* {.final.} = object
|
||||||
`type`*: TGdkEventType
|
`type`*: TGdkEventType
|
||||||
window*: PGdkWindow
|
window*: PGdkWindow
|
||||||
send_event*: gint8
|
send_event*: gint8
|
||||||
|
|
@ -512,7 +512,7 @@ type
|
||||||
new_window_state*: TGdkWindowState
|
new_window_state*: TGdkWindowState
|
||||||
|
|
||||||
PGdkEventDND* = ptr TGdkEventDND
|
PGdkEventDND* = ptr TGdkEventDND
|
||||||
TGdkEventDND* = record
|
TGdkEventDND* {.final.} = object
|
||||||
`type`*: TGdkEventType
|
`type`*: TGdkEventType
|
||||||
window*: PGdkWindow
|
window*: PGdkWindow
|
||||||
send_event*: gint8
|
send_event*: gint8
|
||||||
|
|
@ -521,7 +521,7 @@ type
|
||||||
x_root*: gshort
|
x_root*: gshort
|
||||||
y_root*: gshort
|
y_root*: gshort
|
||||||
|
|
||||||
TGdkEvent* = record
|
TGdkEvent* {.final.} = object
|
||||||
data*: array[0..255, char] # union of
|
data*: array[0..255, char] # union of
|
||||||
# `type`: TGdkEventType
|
# `type`: TGdkEventType
|
||||||
# any: TGdkEventAny
|
# any: TGdkEventAny
|
||||||
|
|
@ -585,12 +585,12 @@ type
|
||||||
PGdkAxisUse* = ptr TGdkAxisUse
|
PGdkAxisUse* = ptr TGdkAxisUse
|
||||||
TGdkAxisUse* = int32
|
TGdkAxisUse* = int32
|
||||||
PGdkDeviceKey* = ptr TGdkDeviceKey
|
PGdkDeviceKey* = ptr TGdkDeviceKey
|
||||||
TGdkDeviceKey* = record
|
TGdkDeviceKey* {.final.} = object
|
||||||
keyval*: guint
|
keyval*: guint
|
||||||
modifiers*: TGdkModifierType
|
modifiers*: TGdkModifierType
|
||||||
|
|
||||||
PGdkDeviceAxis* = ptr TGdkDeviceAxis
|
PGdkDeviceAxis* = ptr TGdkDeviceAxis
|
||||||
TGdkDeviceAxis* = record
|
TGdkDeviceAxis* {.final.} = object
|
||||||
use*: TGdkAxisUse
|
use*: TGdkAxisUse
|
||||||
min*: gdouble
|
min*: gdouble
|
||||||
max*: gdouble
|
max*: gdouble
|
||||||
|
|
@ -605,12 +605,12 @@ type
|
||||||
num_keys*: gint
|
num_keys*: gint
|
||||||
keys*: PGdkDeviceKey
|
keys*: PGdkDeviceKey
|
||||||
|
|
||||||
TGdkTimeCoord* = record
|
TGdkTimeCoord* {.final.} = object
|
||||||
time*: guint32
|
time*: guint32
|
||||||
axes*: array[0..(GDK_MAX_TIMECOORD_AXES) - 1, gdouble]
|
axes*: array[0..(GDK_MAX_TIMECOORD_AXES) - 1, gdouble]
|
||||||
|
|
||||||
PGdkKeymapKey* = ptr TGdkKeymapKey
|
PGdkKeymapKey* = ptr TGdkKeymapKey
|
||||||
TGdkKeymapKey* = record
|
TGdkKeymapKey* {.final.} = object
|
||||||
keycode*: guint
|
keycode*: guint
|
||||||
group*: gint
|
group*: gint
|
||||||
level*: gint
|
level*: gint
|
||||||
|
|
@ -624,12 +624,12 @@ type
|
||||||
direction_changed*: proc (keymap: PGdkKeymap){.cdecl.}
|
direction_changed*: proc (keymap: PGdkKeymap){.cdecl.}
|
||||||
|
|
||||||
PGdkPangoAttrStipple* = ptr TGdkPangoAttrStipple
|
PGdkPangoAttrStipple* = ptr TGdkPangoAttrStipple
|
||||||
TGdkPangoAttrStipple* = record
|
TGdkPangoAttrStipple* {.final.} = object
|
||||||
attr*: TPangoAttribute
|
attr*: TPangoAttribute
|
||||||
stipple*: PGdkBitmap
|
stipple*: PGdkBitmap
|
||||||
|
|
||||||
PGdkPangoAttrEmbossed* = ptr TGdkPangoAttrEmbossed
|
PGdkPangoAttrEmbossed* = ptr TGdkPangoAttrEmbossed
|
||||||
TGdkPangoAttrEmbossed* = record
|
TGdkPangoAttrEmbossed* {.final.} = object
|
||||||
attr*: TPangoAttribute
|
attr*: TPangoAttribute
|
||||||
embossed*: gboolean
|
embossed*: gboolean
|
||||||
|
|
||||||
|
|
@ -653,7 +653,7 @@ type
|
||||||
GDK_OVERLAP_RECTANGLE_PART
|
GDK_OVERLAP_RECTANGLE_PART
|
||||||
TGdkSpanFunc* = proc (span: PGdkSpan, data: gpointer){.cdecl.}
|
TGdkSpanFunc* = proc (span: PGdkSpan, data: gpointer){.cdecl.}
|
||||||
PGdkRgbCmap* = ptr TGdkRgbCmap
|
PGdkRgbCmap* = ptr TGdkRgbCmap
|
||||||
TGdkRgbCmap* = record
|
TGdkRgbCmap* {.final.} = object
|
||||||
colors*: array[0..255, guint32]
|
colors*: array[0..255, guint32]
|
||||||
n_colors*: gint
|
n_colors*: gint
|
||||||
info_list*: PGSList
|
info_list*: PGSList
|
||||||
|
|
@ -698,7 +698,7 @@ type
|
||||||
TGdkInputFunction* = proc (data: gpointer, source: gint,
|
TGdkInputFunction* = proc (data: gpointer, source: gint,
|
||||||
condition: TGdkInputCondition){.cdecl.}
|
condition: TGdkInputCondition){.cdecl.}
|
||||||
TGdkDestroyNotify* = proc (data: gpointer){.cdecl.}
|
TGdkDestroyNotify* = proc (data: gpointer){.cdecl.}
|
||||||
TGdkSpan* = record
|
TGdkSpan* {.final.} = object
|
||||||
x*: gint
|
x*: gint
|
||||||
y*: gint
|
y*: gint
|
||||||
width*: gint
|
width*: gint
|
||||||
|
|
@ -731,7 +731,7 @@ type
|
||||||
GDK_WINDOW_EDGE_SOUTH_WEST, GDK_WINDOW_EDGE_SOUTH,
|
GDK_WINDOW_EDGE_SOUTH_WEST, GDK_WINDOW_EDGE_SOUTH,
|
||||||
GDK_WINDOW_EDGE_SOUTH_EAST
|
GDK_WINDOW_EDGE_SOUTH_EAST
|
||||||
PGdkWindowAttr* = ptr TGdkWindowAttr
|
PGdkWindowAttr* = ptr TGdkWindowAttr
|
||||||
TGdkWindowAttr* = record
|
TGdkWindowAttr* {.final.} = object
|
||||||
title*: cstring
|
title*: cstring
|
||||||
event_mask*: gint
|
event_mask*: gint
|
||||||
x*: gint
|
x*: gint
|
||||||
|
|
@ -748,7 +748,7 @@ type
|
||||||
override_redirect*: gboolean
|
override_redirect*: gboolean
|
||||||
|
|
||||||
PGdkGeometry* = ptr TGdkGeometry
|
PGdkGeometry* = ptr TGdkGeometry
|
||||||
TGdkGeometry* = record
|
TGdkGeometry* {.final.} = object
|
||||||
min_width*: gint
|
min_width*: gint
|
||||||
min_height*: gint
|
min_height*: gint
|
||||||
max_width*: gint
|
max_width*: gint
|
||||||
|
|
@ -762,7 +762,7 @@ type
|
||||||
win_gravity*: TGdkGravity
|
win_gravity*: TGdkGravity
|
||||||
|
|
||||||
PGdkPointerHooks* = ptr TGdkPointerHooks
|
PGdkPointerHooks* = ptr TGdkPointerHooks
|
||||||
TGdkPointerHooks* = record
|
TGdkPointerHooks* {.final.} = object
|
||||||
get_pointer*: proc (window: PGdkWindow, x: Pgint, y: Pgint,
|
get_pointer*: proc (window: PGdkWindow, x: Pgint, y: Pgint,
|
||||||
mask: PGdkModifierType): PGdkWindow{.cdecl.}
|
mask: PGdkModifierType): PGdkWindow{.cdecl.}
|
||||||
window_at_pointer*: proc (screen: PGdkScreen, win_x: Pgint, win_y: Pgint): PGdkWindow{.
|
window_at_pointer*: proc (screen: PGdkScreen, win_x: Pgint, win_y: Pgint): PGdkWindow{.
|
||||||
|
|
|
||||||
|
|
@ -191,12 +191,12 @@ proc gdk_pixbuf_get_option*(pixbuf: PGdkPixbuf, key: cstring): cstring{.cdecl,
|
||||||
dynlib: gdkpixbuflib, importc: "gdk_pixbuf_get_option".}
|
dynlib: gdkpixbuflib, importc: "gdk_pixbuf_get_option".}
|
||||||
type
|
type
|
||||||
PGdkPixbufLoader* = ptr TGdkPixbufLoader
|
PGdkPixbufLoader* = ptr TGdkPixbufLoader
|
||||||
TGdkPixbufLoader* = record
|
TGdkPixbufLoader* {.final.} = object
|
||||||
parent_instance*: TGObject
|
parent_instance*: TGObject
|
||||||
priv*: gpointer
|
priv*: gpointer
|
||||||
|
|
||||||
PGdkPixbufLoaderClass* = ptr TGdkPixbufLoaderClass
|
PGdkPixbufLoaderClass* = ptr TGdkPixbufLoaderClass
|
||||||
TGdkPixbufLoaderClass* = record
|
TGdkPixbufLoaderClass* {.final.} = object
|
||||||
parent_class*: TGObjectClass
|
parent_class*: TGObjectClass
|
||||||
area_prepared*: proc (loader: PGdkPixbufLoader){.cdecl.}
|
area_prepared*: proc (loader: PGdkPixbufLoader){.cdecl.}
|
||||||
area_updated*: proc (loader: PGdkPixbufLoader, x: int32, y: int32,
|
area_updated*: proc (loader: PGdkPixbufLoader, x: int32, y: int32,
|
||||||
|
|
|
||||||
|
|
@ -61,7 +61,7 @@ type
|
||||||
TGHFunc* = proc (key, value, user_data: gpointer){.cdecl.}
|
TGHFunc* = proc (key, value, user_data: gpointer){.cdecl.}
|
||||||
PGFreeFunc* = proc (data: gpointer){.cdecl.}
|
PGFreeFunc* = proc (data: gpointer){.cdecl.}
|
||||||
PGTimeVal* = ptr TGTimeVal
|
PGTimeVal* = ptr TGTimeVal
|
||||||
TGTimeVal* = record
|
TGTimeVal* {.final.} = object
|
||||||
tv_sec*: glong
|
tv_sec*: glong
|
||||||
tv_usec*: glong
|
tv_usec*: glong
|
||||||
|
|
||||||
|
|
@ -88,17 +88,17 @@ type
|
||||||
TGQuark* = guint32
|
TGQuark* = guint32
|
||||||
PGQuark* = ptr TGQuark
|
PGQuark* = ptr TGQuark
|
||||||
PGTypeCValue* = ptr TGTypeCValue
|
PGTypeCValue* = ptr TGTypeCValue
|
||||||
TGTypeCValue* = record
|
TGTypeCValue* {.final.} = object
|
||||||
v_double*: gdouble
|
v_double*: gdouble
|
||||||
|
|
||||||
GType* = gulong
|
GType* = gulong
|
||||||
PGType* = ptr GType
|
PGType* = ptr GType
|
||||||
PGTypeClass* = ptr TGTypeClass
|
PGTypeClass* = ptr TGTypeClass
|
||||||
TGTypeClass* = record
|
TGTypeClass* {.final.} = object
|
||||||
g_type*: GType
|
g_type*: GType
|
||||||
|
|
||||||
PGTypeInstance* = ptr TGTypeInstance
|
PGTypeInstance* = ptr TGTypeInstance
|
||||||
TGTypeInstance* = record
|
TGTypeInstance* {.final.} = object
|
||||||
g_class*: PGTypeClass
|
g_class*: PGTypeClass
|
||||||
|
|
||||||
PGTypeInterface* = ptr TGTypeInterface
|
PGTypeInterface* = ptr TGTypeInterface
|
||||||
|
|
@ -107,14 +107,14 @@ type
|
||||||
g_instance_type*: GType
|
g_instance_type*: GType
|
||||||
|
|
||||||
PGTypeQuery* = ptr TGTypeQuery
|
PGTypeQuery* = ptr TGTypeQuery
|
||||||
TGTypeQuery* = record
|
TGTypeQuery* {.final.} = object
|
||||||
theType*: GType
|
theType*: GType
|
||||||
type_name*: cstring
|
type_name*: cstring
|
||||||
class_size*: guint
|
class_size*: guint
|
||||||
instance_size*: guint
|
instance_size*: guint
|
||||||
|
|
||||||
PGValue* = ptr TGValue
|
PGValue* = ptr TGValue
|
||||||
TGValue* = record
|
TGValue* {.final.} = object
|
||||||
g_type*: GType
|
g_type*: GType
|
||||||
data*: array[0..1, gdouble]
|
data*: array[0..1, gdouble]
|
||||||
|
|
||||||
|
|
@ -122,12 +122,12 @@ type
|
||||||
PGData* = pointer
|
PGData* = pointer
|
||||||
PGSList* = ptr TGSList
|
PGSList* = ptr TGSList
|
||||||
PPGSList* = ptr PGSList
|
PPGSList* = ptr PGSList
|
||||||
TGSList* = record
|
TGSList* {.final.} = object
|
||||||
data*: gpointer
|
data*: gpointer
|
||||||
next*: PGSList
|
next*: PGSList
|
||||||
|
|
||||||
PGList* = ptr TGList
|
PGList* = ptr TGList
|
||||||
TGList* = record
|
TGList* {.final.} = object
|
||||||
data*: gpointer
|
data*: gpointer
|
||||||
next*: PGList
|
next*: PGList
|
||||||
prev*: PGList
|
prev*: PGList
|
||||||
|
|
@ -136,7 +136,7 @@ type
|
||||||
TGParamFlags* = int32
|
TGParamFlags* = int32
|
||||||
PGParamSpec* = ptr TGParamSpec
|
PGParamSpec* = ptr TGParamSpec
|
||||||
PPGParamSpec* = ptr PGParamSpec
|
PPGParamSpec* = ptr PGParamSpec
|
||||||
TGParamSpec* = record
|
TGParamSpec* {.final.} = object
|
||||||
g_type_instance*: TGTypeInstance
|
g_type_instance*: TGTypeInstance
|
||||||
name*: cstring
|
name*: cstring
|
||||||
flags*: TGParamFlags
|
flags*: TGParamFlags
|
||||||
|
|
@ -149,7 +149,7 @@ type
|
||||||
param_id*: guint
|
param_id*: guint
|
||||||
|
|
||||||
PGParamSpecClass* = ptr TGParamSpecClass
|
PGParamSpecClass* = ptr TGParamSpecClass
|
||||||
TGParamSpecClass* = record
|
TGParamSpecClass* {.final.} = object
|
||||||
g_type_class*: TGTypeClass
|
g_type_class*: TGTypeClass
|
||||||
value_type*: GType
|
value_type*: GType
|
||||||
finalize*: proc (pspec: PGParamSpec){.cdecl.}
|
finalize*: proc (pspec: PGParamSpec){.cdecl.}
|
||||||
|
|
@ -160,7 +160,7 @@ type
|
||||||
dummy*: array[0..3, gpointer]
|
dummy*: array[0..3, gpointer]
|
||||||
|
|
||||||
PGParameter* = ptr TGParameter
|
PGParameter* = ptr TGParameter
|
||||||
TGParameter* = record
|
TGParameter* {.final.} = object
|
||||||
name*: cstring
|
name*: cstring
|
||||||
value*: TGValue
|
value*: TGValue
|
||||||
|
|
||||||
|
|
@ -305,7 +305,7 @@ const
|
||||||
|
|
||||||
type
|
type
|
||||||
PGTypeValueTable* = ptr TGTypeValueTable
|
PGTypeValueTable* = ptr TGTypeValueTable
|
||||||
TGTypeValueTable* = record
|
TGTypeValueTable* {.final.} = object
|
||||||
value_init*: proc (value: PGValue){.cdecl.}
|
value_init*: proc (value: PGValue){.cdecl.}
|
||||||
value_free*: proc (value: PGValue){.cdecl.}
|
value_free*: proc (value: PGValue){.cdecl.}
|
||||||
value_copy*: proc (src_value: PGValue, dest_value: PGValue){.cdecl.}
|
value_copy*: proc (src_value: PGValue, dest_value: PGValue){.cdecl.}
|
||||||
|
|
@ -320,7 +320,7 @@ type
|
||||||
cdecl.}
|
cdecl.}
|
||||||
|
|
||||||
PGTypeInfo* = ptr TGTypeInfo
|
PGTypeInfo* = ptr TGTypeInfo
|
||||||
TGTypeInfo* = record
|
TGTypeInfo* {.final.} = object
|
||||||
class_size*: guint16
|
class_size*: guint16
|
||||||
base_init*: TGBaseInitFunc
|
base_init*: TGBaseInitFunc
|
||||||
base_finalize*: TGBaseFinalizeFunc
|
base_finalize*: TGBaseFinalizeFunc
|
||||||
|
|
@ -333,11 +333,11 @@ type
|
||||||
value_table*: PGTypeValueTable
|
value_table*: PGTypeValueTable
|
||||||
|
|
||||||
PGTypeFundamentalInfo* = ptr TGTypeFundamentalInfo
|
PGTypeFundamentalInfo* = ptr TGTypeFundamentalInfo
|
||||||
TGTypeFundamentalInfo* = record
|
TGTypeFundamentalInfo* {.final.} = object
|
||||||
type_flags*: TGTypeFundamentalFlags
|
type_flags*: TGTypeFundamentalFlags
|
||||||
|
|
||||||
PGInterfaceInfo* = ptr TGInterfaceInfo
|
PGInterfaceInfo* = ptr TGInterfaceInfo
|
||||||
TGInterfaceInfo* = record
|
TGInterfaceInfo* {.final.} = object
|
||||||
interface_init*: TGInterfaceInitFunc
|
interface_init*: TGInterfaceInitFunc
|
||||||
interface_finalize*: TGInterfaceFinalizeFunc
|
interface_finalize*: TGInterfaceFinalizeFunc
|
||||||
interface_data*: gpointer
|
interface_data*: gpointer
|
||||||
|
|
@ -449,7 +449,7 @@ const
|
||||||
|
|
||||||
type
|
type
|
||||||
PGValueArray* = ptr TGValueArray
|
PGValueArray* = ptr TGValueArray
|
||||||
TGValueArray* = record
|
TGValueArray* {.final.} = object
|
||||||
n_values*: guint
|
n_values*: guint
|
||||||
values*: PGValue
|
values*: PGValue
|
||||||
n_prealloced*: guint
|
n_prealloced*: guint
|
||||||
|
|
@ -628,7 +628,7 @@ proc g_value_set_param_take_ownership*(value: PGValue, param: PGParamSpec){.
|
||||||
cdecl, dynlib: gliblib, importc: "g_value_set_param_take_ownership".}
|
cdecl, dynlib: gliblib, importc: "g_value_set_param_take_ownership".}
|
||||||
type
|
type
|
||||||
PGParamSpecTypeInfo* = ptr TGParamSpecTypeInfo
|
PGParamSpecTypeInfo* = ptr TGParamSpecTypeInfo
|
||||||
TGParamSpecTypeInfo* = record
|
TGParamSpecTypeInfo* {.final.} = object
|
||||||
instance_size*: guint16
|
instance_size*: guint16
|
||||||
n_preallocs*: guint16
|
n_preallocs*: guint16
|
||||||
instance_init*: proc (pspec: PGParamSpec){.cdecl.}
|
instance_init*: proc (pspec: PGParamSpec){.cdecl.}
|
||||||
|
|
@ -668,7 +668,7 @@ type
|
||||||
PGClosure* = ptr TGClosure
|
PGClosure* = ptr TGClosure
|
||||||
PGClosureNotifyData* = ptr TGClosureNotifyData
|
PGClosureNotifyData* = ptr TGClosureNotifyData
|
||||||
TGClosureNotify* = proc (data: gpointer, closure: PGClosure){.cdecl.}
|
TGClosureNotify* = proc (data: gpointer, closure: PGClosure){.cdecl.}
|
||||||
TGClosure* = record
|
TGClosure* {.final.} = object
|
||||||
flag0*: int32
|
flag0*: int32
|
||||||
marshal*: proc (closure: PGClosure, return_value: PGValue,
|
marshal*: proc (closure: PGClosure, return_value: PGValue,
|
||||||
n_param_values: guint, param_values: PGValue,
|
n_param_values: guint, param_values: PGValue,
|
||||||
|
|
@ -682,7 +682,7 @@ type
|
||||||
n_param_values: guint, param_values: PGValue,
|
n_param_values: guint, param_values: PGValue,
|
||||||
invocation_hint: gpointer, marshal_data: gpointer){.
|
invocation_hint: gpointer, marshal_data: gpointer){.
|
||||||
cdecl.}
|
cdecl.}
|
||||||
TGClosureNotifyData* = record
|
TGClosureNotifyData* {.final.} = object
|
||||||
data*: gpointer
|
data*: gpointer
|
||||||
notify*: TGClosureNotify
|
notify*: TGClosureNotify
|
||||||
|
|
||||||
|
|
@ -734,7 +734,7 @@ proc is_invalid*(a: var TGClosure): guint
|
||||||
proc set_is_invalid*(a: var TGClosure, is_invalid: guint)
|
proc set_is_invalid*(a: var TGClosure, is_invalid: guint)
|
||||||
type
|
type
|
||||||
PGCClosure* = ptr TGCClosure
|
PGCClosure* = ptr TGCClosure
|
||||||
TGCClosure* = record
|
TGCClosure* {.final.} = object
|
||||||
closure*: TGClosure
|
closure*: TGClosure
|
||||||
callback*: gpointer
|
callback*: gpointer
|
||||||
|
|
||||||
|
|
@ -797,13 +797,13 @@ type
|
||||||
data: gpointer): gboolean{.cdecl.}
|
data: gpointer): gboolean{.cdecl.}
|
||||||
PGSignalFlags* = ptr TGSignalFlags
|
PGSignalFlags* = ptr TGSignalFlags
|
||||||
TGSignalFlags* = int32
|
TGSignalFlags* = int32
|
||||||
TGSignalInvocationHint* = record
|
TGSignalInvocationHint* {.final.} = object
|
||||||
signal_id*: guint
|
signal_id*: guint
|
||||||
detail*: TGQuark
|
detail*: TGQuark
|
||||||
run_type*: TGSignalFlags
|
run_type*: TGSignalFlags
|
||||||
|
|
||||||
PGSignalQuery* = ptr TGSignalQuery
|
PGSignalQuery* = ptr TGSignalQuery
|
||||||
TGSignalQuery* = record
|
TGSignalQuery* {.final.} = object
|
||||||
signal_id*: guint
|
signal_id*: guint
|
||||||
signal_name*: cstring
|
signal_name*: cstring
|
||||||
itype*: GType
|
itype*: GType
|
||||||
|
|
@ -952,7 +952,7 @@ type
|
||||||
TGTypePluginCompleteInterfaceInfo* = proc (plugin: PGTypePlugin,
|
TGTypePluginCompleteInterfaceInfo* = proc (plugin: PGTypePlugin,
|
||||||
instance_type: GType, interface_type: GType, info: PGInterfaceInfo){.cdecl.}
|
instance_type: GType, interface_type: GType, info: PGInterfaceInfo){.cdecl.}
|
||||||
PGTypePluginClass* = ptr TGTypePluginClass
|
PGTypePluginClass* = ptr TGTypePluginClass
|
||||||
TGTypePluginClass* = record
|
TGTypePluginClass* {.final.} = object
|
||||||
base_iface*: TGTypeInterface
|
base_iface*: TGTypeInterface
|
||||||
use_plugin*: TGTypePluginUse
|
use_plugin*: TGTypePluginUse
|
||||||
unuse_plugin*: TGTypePluginUnuse
|
unuse_plugin*: TGTypePluginUnuse
|
||||||
|
|
@ -1011,7 +1011,7 @@ type
|
||||||
notify*: proc (anObject: PGObject, pspec: PGParamSpec){.cdecl.}
|
notify*: proc (anObject: PGObject, pspec: PGParamSpec){.cdecl.}
|
||||||
pdummy*: array[0..7, gpointer]
|
pdummy*: array[0..7, gpointer]
|
||||||
|
|
||||||
TGObjectConstructParam* = record
|
TGObjectConstructParam* {.final.} = object
|
||||||
pspec*: PGParamSpec
|
pspec*: PGParamSpec
|
||||||
value*: PGValue
|
value*: PGValue
|
||||||
|
|
||||||
|
|
@ -1125,27 +1125,27 @@ proc GUINT32_SWAP_LE_BE_CONSTANT*(val: guint32): guint32
|
||||||
type
|
type
|
||||||
PGEnumClass* = ptr TGEnumClass
|
PGEnumClass* = ptr TGEnumClass
|
||||||
PGEnumValue* = ptr TGEnumValue
|
PGEnumValue* = ptr TGEnumValue
|
||||||
TGEnumClass* = record
|
TGEnumClass* {.final.} = object
|
||||||
g_type_class*: TGTypeClass
|
g_type_class*: TGTypeClass
|
||||||
minimum*: gint
|
minimum*: gint
|
||||||
maximum*: gint
|
maximum*: gint
|
||||||
n_values*: guint
|
n_values*: guint
|
||||||
values*: PGEnumValue
|
values*: PGEnumValue
|
||||||
|
|
||||||
TGEnumValue* = record
|
TGEnumValue* {.final.} = object
|
||||||
value*: gint
|
value*: gint
|
||||||
value_name*: cstring
|
value_name*: cstring
|
||||||
value_nick*: cstring
|
value_nick*: cstring
|
||||||
|
|
||||||
PGFlagsClass* = ptr TGFlagsClass
|
PGFlagsClass* = ptr TGFlagsClass
|
||||||
PGFlagsValue* = ptr TGFlagsValue
|
PGFlagsValue* = ptr TGFlagsValue
|
||||||
TGFlagsClass* = record
|
TGFlagsClass* {.final.} = object
|
||||||
g_type_class*: TGTypeClass
|
g_type_class*: TGTypeClass
|
||||||
mask*: guint
|
mask*: guint
|
||||||
n_values*: guint
|
n_values*: guint
|
||||||
values*: PGFlagsValue
|
values*: PGFlagsValue
|
||||||
|
|
||||||
TGFlagsValue* = record
|
TGFlagsValue* {.final.} = object
|
||||||
value*: guint
|
value*: guint
|
||||||
value_name*: cstring
|
value_name*: cstring
|
||||||
value_nick*: cstring
|
value_nick*: cstring
|
||||||
|
|
@ -1203,7 +1203,7 @@ const
|
||||||
G_MAXUSHORT* = 2 * G_MAXSHORT + 1
|
G_MAXUSHORT* = 2 * G_MAXSHORT + 1
|
||||||
G_MAXINT* = 2147483647
|
G_MAXINT* = 2147483647
|
||||||
G_MININT* = - G_MAXINT - 1
|
G_MININT* = - G_MAXINT - 1
|
||||||
G_MAXUINT* = 4294967295
|
G_MAXUINT* = -1
|
||||||
G_MINLONG* = G_MININT
|
G_MINLONG* = G_MININT
|
||||||
G_MAXLONG* = G_MAXINT
|
G_MAXLONG* = G_MAXINT
|
||||||
G_MAXULONG* = G_MAXUINT
|
G_MAXULONG* = G_MAXUINT
|
||||||
|
|
@ -1224,7 +1224,7 @@ const
|
||||||
|
|
||||||
type
|
type
|
||||||
PGSystemThread* = ptr TGSystemThread
|
PGSystemThread* = ptr TGSystemThread
|
||||||
TGSystemThread* = record
|
TGSystemThread* {.final.} = object
|
||||||
data*: array[0..3, char]
|
data*: array[0..3, char]
|
||||||
dummy_double*: float64
|
dummy_double*: float64
|
||||||
dummy_pointer*: pointer
|
dummy_pointer*: pointer
|
||||||
|
|
@ -1350,7 +1350,7 @@ proc g_set_prgname*(prgname: cstring){.cdecl, dynlib: gliblib,
|
||||||
importc: "g_set_prgname".}
|
importc: "g_set_prgname".}
|
||||||
type
|
type
|
||||||
PGDebugKey* = ptr TGDebugKey
|
PGDebugKey* = ptr TGDebugKey
|
||||||
TGDebugKey* = record
|
TGDebugKey* {.final.} = object
|
||||||
key*: cstring
|
key*: cstring
|
||||||
value*: guint
|
value*: guint
|
||||||
|
|
||||||
|
|
@ -1390,7 +1390,7 @@ proc g_bit_storage*(number: gulong): guint{.cdecl, dynlib: gliblib,
|
||||||
type
|
type
|
||||||
PPGTrashStack* = ptr PGTrashStack
|
PPGTrashStack* = ptr PGTrashStack
|
||||||
PGTrashStack* = ptr TGTrashStack
|
PGTrashStack* = ptr TGTrashStack
|
||||||
TGTrashStack* = record
|
TGTrashStack* {.final.} = object
|
||||||
next*: PGTrashStack
|
next*: PGTrashStack
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1466,7 +1466,7 @@ const
|
||||||
|
|
||||||
type
|
type
|
||||||
PGMemVTable* = ptr TGMemVTable
|
PGMemVTable* = ptr TGMemVTable
|
||||||
TGMemVTable* = record
|
TGMemVTable* {.final.} = object
|
||||||
malloc*: proc (n_bytes: gsize): gpointer{.cdecl.}
|
malloc*: proc (n_bytes: gsize): gpointer{.cdecl.}
|
||||||
realloc*: proc (mem: gpointer, n_bytes: gsize): gpointer{.cdecl.}
|
realloc*: proc (mem: gpointer, n_bytes: gsize): gpointer{.cdecl.}
|
||||||
free*: proc (mem: gpointer){.cdecl.}
|
free*: proc (mem: gpointer){.cdecl.}
|
||||||
|
|
@ -1679,7 +1679,7 @@ type
|
||||||
TGCompletionStrncmpFunc* = proc (s1: cstring, s2: cstring, n: gsize): gint{.
|
TGCompletionStrncmpFunc* = proc (s1: cstring, s2: cstring, n: gsize): gint{.
|
||||||
cdecl.}
|
cdecl.}
|
||||||
PGCompletion* = ptr TGCompletion
|
PGCompletion* = ptr TGCompletion
|
||||||
TGCompletion* = record
|
TGCompletion* {.final.} = object
|
||||||
items*: PGList
|
items*: PGList
|
||||||
func*: TGCompletionFunc
|
func*: TGCompletionFunc
|
||||||
prefix*: cstring
|
prefix*: cstring
|
||||||
|
|
@ -1809,7 +1809,7 @@ type
|
||||||
PGDateDay* = ptr TGDateDay
|
PGDateDay* = ptr TGDateDay
|
||||||
TGDateDay* = guint8
|
TGDateDay* = guint8
|
||||||
Ptm* = ptr Ttm
|
Ptm* = ptr Ttm
|
||||||
Ttm* = record
|
Ttm* {.final.} = object
|
||||||
tm_sec*: gint
|
tm_sec*: gint
|
||||||
tm_min*: gint
|
tm_min*: gint
|
||||||
tm_hour*: gint
|
tm_hour*: gint
|
||||||
|
|
@ -1872,7 +1872,7 @@ const
|
||||||
|
|
||||||
type
|
type
|
||||||
PGDate* = ptr TGDate
|
PGDate* = ptr TGDate
|
||||||
TGDate* = record
|
TGDate* {.final.} = object
|
||||||
flag0*: int32
|
flag0*: int32
|
||||||
flag1*: int32
|
flag1*: int32
|
||||||
|
|
||||||
|
|
@ -2028,7 +2028,7 @@ proc g_file_open_tmp*(tmpl: cstring, name_used: PPchar, error: pointer): int32{.
|
||||||
cdecl, dynlib: gliblib, importc: "g_file_open_tmp".}
|
cdecl, dynlib: gliblib, importc: "g_file_open_tmp".}
|
||||||
type
|
type
|
||||||
PGHook* = ptr TGHook
|
PGHook* = ptr TGHook
|
||||||
TGHook* = record
|
TGHook* {.final.} = object
|
||||||
data*: gpointer
|
data*: gpointer
|
||||||
next*: PGHook
|
next*: PGHook
|
||||||
prev*: PGHook
|
prev*: PGHook
|
||||||
|
|
@ -2047,7 +2047,7 @@ type
|
||||||
TGHookFunc* = proc (data: gpointer){.cdecl.}
|
TGHookFunc* = proc (data: gpointer){.cdecl.}
|
||||||
TGHookCheckFunc* = proc (data: gpointer): gboolean{.cdecl.}
|
TGHookCheckFunc* = proc (data: gpointer): gboolean{.cdecl.}
|
||||||
TGHookFinalizeFunc* = proc (hook_list: PGHookList, hook: PGHook){.cdecl.}
|
TGHookFinalizeFunc* = proc (hook_list: PGHookList, hook: PGHook){.cdecl.}
|
||||||
TGHookList* = record
|
TGHookList* {.final.} = object
|
||||||
seq_id*: gulong
|
seq_id*: gulong
|
||||||
flag0*: int32
|
flag0*: int32
|
||||||
hooks*: PGHook
|
hooks*: PGHook
|
||||||
|
|
@ -2138,7 +2138,7 @@ proc g_hook_list_marshal_check*(hook_list: PGHookList, may_recurse: gboolean,
|
||||||
importc: "g_hook_list_marshal_check".}
|
importc: "g_hook_list_marshal_check".}
|
||||||
type
|
type
|
||||||
PGThreadPool* = ptr TGThreadPool
|
PGThreadPool* = ptr TGThreadPool
|
||||||
TGThreadPool* = record
|
TGThreadPool* {.final.} = object
|
||||||
func*: TGFunc
|
func*: TGFunc
|
||||||
user_data*: gpointer
|
user_data*: gpointer
|
||||||
exclusive*: gboolean
|
exclusive*: gboolean
|
||||||
|
|
@ -2352,7 +2352,7 @@ proc g_utf8_collate_key*(str: cstring, len: gssize): cstring{.cdecl,
|
||||||
dynlib: gliblib, importc: "g_utf8_collate_key".}
|
dynlib: gliblib, importc: "g_utf8_collate_key".}
|
||||||
type
|
type
|
||||||
PGString* = ptr TGString
|
PGString* = ptr TGString
|
||||||
TGString* = record
|
TGString* {.final.} = object
|
||||||
str*: cstring
|
str*: cstring
|
||||||
len*: gsize
|
len*: gsize
|
||||||
allocated_len*: gsize
|
allocated_len*: gsize
|
||||||
|
|
@ -2468,7 +2468,7 @@ type
|
||||||
TGIOFunc* = proc (source: PGIOChannel, condition: TGIOCondition,
|
TGIOFunc* = proc (source: PGIOChannel, condition: TGIOCondition,
|
||||||
data: gpointer): gboolean{.cdecl.}
|
data: gpointer): gboolean{.cdecl.}
|
||||||
PGIOFuncs* = ptr TGIOFuncs
|
PGIOFuncs* = ptr TGIOFuncs
|
||||||
TGIOFuncs* = record
|
TGIOFuncs* {.final.} = object
|
||||||
io_read*: proc (channel: PGIOChannel, buf: cstring, count: gsize,
|
io_read*: proc (channel: PGIOChannel, buf: cstring, count: gsize,
|
||||||
bytes_read: Pgsize, err: pointer): TGIOStatus{.cdecl.}
|
bytes_read: Pgsize, err: pointer): TGIOStatus{.cdecl.}
|
||||||
io_write*: proc (channel: PGIOChannel, buf: cstring, count: gsize,
|
io_write*: proc (channel: PGIOChannel, buf: cstring, count: gsize,
|
||||||
|
|
@ -2483,7 +2483,7 @@ type
|
||||||
cdecl.}
|
cdecl.}
|
||||||
io_get_flags*: proc (channel: PGIOChannel): TGIOFlags{.cdecl.}
|
io_get_flags*: proc (channel: PGIOChannel): TGIOFlags{.cdecl.}
|
||||||
|
|
||||||
TGIOChannel* = record
|
TGIOChannel* {.final.} = object
|
||||||
ref_count*: guint
|
ref_count*: guint
|
||||||
funcs*: PGIOFuncs
|
funcs*: PGIOFuncs
|
||||||
encoding*: cstring
|
encoding*: cstring
|
||||||
|
|
@ -2699,7 +2699,7 @@ type
|
||||||
PGMarkupParseContext* = ptr TGMarkupParseContext
|
PGMarkupParseContext* = ptr TGMarkupParseContext
|
||||||
TGMarkupParseContext* = pointer
|
TGMarkupParseContext* = pointer
|
||||||
PGMarkupParser* = ptr TGMarkupParser
|
PGMarkupParser* = ptr TGMarkupParser
|
||||||
TGMarkupParser* = record
|
TGMarkupParser* {.final.} = object
|
||||||
start_element*: proc (context: PGMarkupParseContext, element_name: cstring,
|
start_element*: proc (context: PGMarkupParseContext, element_name: cstring,
|
||||||
attribute_names: PPgchar, attribute_values: PPgchar,
|
attribute_names: PPgchar, attribute_values: PPgchar,
|
||||||
user_data: gpointer, error: pointer){.cdecl.}
|
user_data: gpointer, error: pointer){.cdecl.}
|
||||||
|
|
@ -2733,7 +2733,7 @@ proc g_markup_escape_text*(text: cstring, length: gssize): cstring{.cdecl,
|
||||||
dynlib: gliblib, importc: "g_markup_escape_text".}
|
dynlib: gliblib, importc: "g_markup_escape_text".}
|
||||||
type
|
type
|
||||||
PGNode* = ptr TGNode
|
PGNode* = ptr TGNode
|
||||||
TGNode* = record
|
TGNode* {.final.} = object
|
||||||
data*: gpointer
|
data*: gpointer
|
||||||
next*: PGNode
|
next*: PGNode
|
||||||
prev*: PGNode
|
prev*: PGNode
|
||||||
|
|
@ -2886,7 +2886,7 @@ proc g_qsort_with_data*(pbase: gconstpointer, total_elems: gint, size: gsize,
|
||||||
cdecl, dynlib: gliblib, importc: "g_qsort_with_data".}
|
cdecl, dynlib: gliblib, importc: "g_qsort_with_data".}
|
||||||
type
|
type
|
||||||
PGQueue* = ptr TGQueue
|
PGQueue* = ptr TGQueue
|
||||||
TGQueue* = record
|
TGQueue* {.final.} = object
|
||||||
head*: PGList
|
head*: PGList
|
||||||
tail*: PGList
|
tail*: PGList
|
||||||
length*: guint
|
length*: guint
|
||||||
|
|
@ -2947,7 +2947,7 @@ proc g_random_double_range*(`begin`: gdouble, `end`: gdouble): gdouble{.cdecl,
|
||||||
dynlib: gliblib, importc: "g_random_double_range".}
|
dynlib: gliblib, importc: "g_random_double_range".}
|
||||||
type
|
type
|
||||||
PGTuples* = ptr TGTuples
|
PGTuples* = ptr TGTuples
|
||||||
TGTuples* = record
|
TGTuples* {.final.} = object
|
||||||
len*: guint
|
len*: guint
|
||||||
|
|
||||||
PGRelation* = pointer
|
PGRelation* = pointer
|
||||||
|
|
@ -3003,12 +3003,12 @@ type
|
||||||
PGScanner* = ptr TGScanner
|
PGScanner* = ptr TGScanner
|
||||||
PGScannerConfig* = ptr TGScannerConfig
|
PGScannerConfig* = ptr TGScannerConfig
|
||||||
PGTokenValue* = ptr TGTokenValue
|
PGTokenValue* = ptr TGTokenValue
|
||||||
TGTokenValue* = record
|
TGTokenValue* {.final.} = object
|
||||||
v_float*: gdouble
|
v_float*: gdouble
|
||||||
|
|
||||||
TGScannerMsgFunc* = proc (scanner: PGScanner, message: cstring,
|
TGScannerMsgFunc* = proc (scanner: PGScanner, message: cstring,
|
||||||
error: gboolean){.cdecl.}
|
error: gboolean){.cdecl.}
|
||||||
TGScanner* = record
|
TGScanner* {.final.} = object
|
||||||
user_data*: gpointer
|
user_data*: gpointer
|
||||||
max_parse_errors*: guint
|
max_parse_errors*: guint
|
||||||
parse_errors*: guint
|
parse_errors*: guint
|
||||||
|
|
@ -3031,7 +3031,7 @@ type
|
||||||
scope_id*: guint
|
scope_id*: guint
|
||||||
msg_handler*: TGScannerMsgFunc
|
msg_handler*: TGScannerMsgFunc
|
||||||
|
|
||||||
TGScannerConfig* = record
|
TGScannerConfig* {.final.} = object
|
||||||
cset_skip_characters*: cstring
|
cset_skip_characters*: cstring
|
||||||
cset_identifier_first*: cstring
|
cset_identifier_first*: cstring
|
||||||
cset_identifier_nth*: cstring
|
cset_identifier_nth*: cstring
|
||||||
|
|
|
||||||
|
|
@ -155,17 +155,17 @@ type
|
||||||
TGtkSignalFunc* = proc (para1: TGtkSignalFuncProc){.cdecl.}
|
TGtkSignalFunc* = proc (para1: TGtkSignalFuncProc){.cdecl.}
|
||||||
PGtkSignalMarshaller* = ptr TGtkSignalMarshaller
|
PGtkSignalMarshaller* = ptr TGtkSignalMarshaller
|
||||||
TGtkSignalMarshaller* = TGSignalCMarshaller
|
TGtkSignalMarshaller* = TGSignalCMarshaller
|
||||||
TGtkArgSignalData* = record
|
TGtkArgSignalData* {.final.} = object
|
||||||
f*: TGtkSignalFunc
|
f*: TGtkSignalFunc
|
||||||
d*: gpointer
|
d*: gpointer
|
||||||
|
|
||||||
TGtkArg* = record
|
TGtkArg* {.final.} = object
|
||||||
`type`*: TGtkType
|
`type`*: TGtkType
|
||||||
name*: cstring
|
name*: cstring
|
||||||
d*: gdouble # was a union type
|
d*: gdouble # was a union type
|
||||||
|
|
||||||
PGtkTypeInfo* = ptr TGtkTypeInfo
|
PGtkTypeInfo* = ptr TGtkTypeInfo
|
||||||
TGtkTypeInfo* = record
|
TGtkTypeInfo* {.final.} = object
|
||||||
type_name*: cstring
|
type_name*: cstring
|
||||||
object_size*: guint
|
object_size*: guint
|
||||||
class_size*: guint
|
class_size*: guint
|
||||||
|
|
@ -188,7 +188,7 @@ type
|
||||||
TGtkAllocation* = TGdkRectangle
|
TGtkAllocation* = TGdkRectangle
|
||||||
TGtkCallback* = proc (widget: PGtkWidget, data: gpointer){.cdecl.}
|
TGtkCallback* = proc (widget: PGtkWidget, data: gpointer){.cdecl.}
|
||||||
PGtkRequisition* = ptr TGtkRequisition
|
PGtkRequisition* = ptr TGtkRequisition
|
||||||
TGtkRequisition* = record
|
TGtkRequisition* {.final.} = object
|
||||||
width*: gint
|
width*: gint
|
||||||
height*: gint
|
height*: gint
|
||||||
|
|
||||||
|
|
@ -323,7 +323,7 @@ type
|
||||||
gtk_reserved8*: proc (){.cdecl.}
|
gtk_reserved8*: proc (){.cdecl.}
|
||||||
|
|
||||||
PGtkWidgetAuxInfo* = ptr TGtkWidgetAuxInfo
|
PGtkWidgetAuxInfo* = ptr TGtkWidgetAuxInfo
|
||||||
TGtkWidgetAuxInfo* = record
|
TGtkWidgetAuxInfo* {.final.} = object
|
||||||
x*: gint
|
x*: gint
|
||||||
y*: gint
|
y*: gint
|
||||||
width*: gint
|
width*: gint
|
||||||
|
|
@ -331,7 +331,7 @@ type
|
||||||
flag0*: guint16
|
flag0*: guint16
|
||||||
|
|
||||||
PGtkWidgetShapeInfo* = ptr TGtkWidgetShapeInfo
|
PGtkWidgetShapeInfo* = ptr TGtkWidgetShapeInfo
|
||||||
TGtkWidgetShapeInfo* = record
|
TGtkWidgetShapeInfo* {.final.} = object
|
||||||
offset_x*: gint16
|
offset_x*: gint16
|
||||||
offset_y*: gint16
|
offset_y*: gint16
|
||||||
shape_mask*: PGdkBitmap
|
shape_mask*: PGdkBitmap
|
||||||
|
|
@ -370,12 +370,12 @@ type
|
||||||
gtk_reserved4: proc (){.cdecl.}
|
gtk_reserved4: proc (){.cdecl.}
|
||||||
|
|
||||||
PGtkAccelKey* = ptr TGtkAccelKey
|
PGtkAccelKey* = ptr TGtkAccelKey
|
||||||
TGtkAccelKey* = record
|
TGtkAccelKey* {.final.} = object
|
||||||
accel_key*: guint
|
accel_key*: guint
|
||||||
accel_mods*: TGdkModifierType
|
accel_mods*: TGdkModifierType
|
||||||
flag0*: guint16
|
flag0*: guint16
|
||||||
|
|
||||||
TGtkAccelGroupEntry* = record
|
TGtkAccelGroupEntry* {.final.} = object
|
||||||
key*: TGtkAccelKey
|
key*: TGtkAccelKey
|
||||||
closure*: PGClosure
|
closure*: PGClosure
|
||||||
accel_path_quark*: TGQuark
|
accel_path_quark*: TGQuark
|
||||||
|
|
@ -595,7 +595,7 @@ type
|
||||||
PGtkBindingSignal* = ptr TGtkBindingSignal
|
PGtkBindingSignal* = ptr TGtkBindingSignal
|
||||||
PGtkBindingArg* = ptr TGtkBindingArg
|
PGtkBindingArg* = ptr TGtkBindingArg
|
||||||
PGtkBindingSet* = ptr TGtkBindingSet
|
PGtkBindingSet* = ptr TGtkBindingSet
|
||||||
TGtkBindingSet* = record
|
TGtkBindingSet* {.final.} = object
|
||||||
set_name*: cstring
|
set_name*: cstring
|
||||||
priority*: gint
|
priority*: gint
|
||||||
widget_path_pspecs*: PGSList
|
widget_path_pspecs*: PGSList
|
||||||
|
|
@ -605,7 +605,7 @@ type
|
||||||
current*: PGtkBindingEntry
|
current*: PGtkBindingEntry
|
||||||
flag0*: guint16
|
flag0*: guint16
|
||||||
|
|
||||||
TGtkBindingEntry* = record
|
TGtkBindingEntry* {.final.} = object
|
||||||
keyval*: guint
|
keyval*: guint
|
||||||
modifiers*: TGdkModifierType
|
modifiers*: TGdkModifierType
|
||||||
binding_set*: PGtkBindingSet
|
binding_set*: PGtkBindingSet
|
||||||
|
|
@ -614,13 +614,13 @@ type
|
||||||
hash_next*: PGtkBindingEntry
|
hash_next*: PGtkBindingEntry
|
||||||
signals*: PGtkBindingSignal
|
signals*: PGtkBindingSignal
|
||||||
|
|
||||||
TGtkBindingSignal* = record
|
TGtkBindingSignal* {.final.} = object
|
||||||
next*: PGtkBindingSignal
|
next*: PGtkBindingSignal
|
||||||
signal_name*: cstring
|
signal_name*: cstring
|
||||||
n_args*: guint
|
n_args*: guint
|
||||||
args*: PGtkBindingArg
|
args*: PGtkBindingArg
|
||||||
|
|
||||||
TGtkBindingArg* = record
|
TGtkBindingArg* {.final.} = object
|
||||||
arg_type*: TGtkType
|
arg_type*: TGtkType
|
||||||
d*: gdouble
|
d*: gdouble
|
||||||
|
|
||||||
|
|
@ -634,7 +634,7 @@ type
|
||||||
TGtkBoxClass* = object of TGtkContainerClass
|
TGtkBoxClass* = object of TGtkContainerClass
|
||||||
|
|
||||||
PGtkBoxChild* = ptr TGtkBoxChild
|
PGtkBoxChild* = ptr TGtkBoxChild
|
||||||
TGtkBoxChild* = record
|
TGtkBoxChild* {.final.} = object
|
||||||
widget*: PGtkWidget
|
widget*: PGtkWidget
|
||||||
padding*: guint16
|
padding*: guint16
|
||||||
flag0*: guint16
|
flag0*: guint16
|
||||||
|
|
@ -906,12 +906,12 @@ type
|
||||||
TGtkCListCompareFunc* = proc (clist: PGtkCList, ptr1: gconstpointer,
|
TGtkCListCompareFunc* = proc (clist: PGtkCList, ptr1: gconstpointer,
|
||||||
ptr2: gconstpointer): gint{.cdecl.}
|
ptr2: gconstpointer): gint{.cdecl.}
|
||||||
PGtkCListCellInfo* = ptr TGtkCListCellInfo
|
PGtkCListCellInfo* = ptr TGtkCListCellInfo
|
||||||
TGtkCListCellInfo* = record
|
TGtkCListCellInfo* {.final.} = object
|
||||||
row*: gint
|
row*: gint
|
||||||
column*: gint
|
column*: gint
|
||||||
|
|
||||||
PGtkCListDestInfo* = ptr TGtkCListDestInfo
|
PGtkCListDestInfo* = ptr TGtkCListDestInfo
|
||||||
TGtkCListDestInfo* = record
|
TGtkCListDestInfo* {.final.} = object
|
||||||
cell*: TGtkCListCellInfo
|
cell*: TGtkCListCellInfo
|
||||||
insert_pos*: TGtkCListDragPos
|
insert_pos*: TGtkCListDragPos
|
||||||
|
|
||||||
|
|
@ -1014,7 +1014,7 @@ type
|
||||||
|
|
||||||
PGPtrArray = pointer
|
PGPtrArray = pointer
|
||||||
PGArray = pointer
|
PGArray = pointer
|
||||||
TGtkCListColumn* = record
|
TGtkCListColumn* {.final.} = object
|
||||||
title*: cstring
|
title*: cstring
|
||||||
area*: TGdkRectangle
|
area*: TGdkRectangle
|
||||||
button*: PGtkWidget
|
button*: PGtkWidget
|
||||||
|
|
@ -1025,7 +1025,7 @@ type
|
||||||
justification*: TGtkJustification
|
justification*: TGtkJustification
|
||||||
flag0*: guint16
|
flag0*: guint16
|
||||||
|
|
||||||
TGtkCListRow* = record
|
TGtkCListRow* {.final.} = object
|
||||||
cell*: PGtkCell
|
cell*: PGtkCell
|
||||||
state*: TGtkStateType
|
state*: TGtkStateType
|
||||||
foreground*: TGdkColor
|
foreground*: TGdkColor
|
||||||
|
|
@ -1036,7 +1036,7 @@ type
|
||||||
flag0*: guint16
|
flag0*: guint16
|
||||||
|
|
||||||
PGtkCellText* = ptr TGtkCellText
|
PGtkCellText* = ptr TGtkCellText
|
||||||
TGtkCellText* = record
|
TGtkCellText* {.final.} = object
|
||||||
`type`*: TGtkCellType
|
`type`*: TGtkCellType
|
||||||
vertical*: gint16
|
vertical*: gint16
|
||||||
horizontal*: gint16
|
horizontal*: gint16
|
||||||
|
|
@ -1044,7 +1044,7 @@ type
|
||||||
text*: cstring
|
text*: cstring
|
||||||
|
|
||||||
PGtkCellPixmap* = ptr TGtkCellPixmap
|
PGtkCellPixmap* = ptr TGtkCellPixmap
|
||||||
TGtkCellPixmap* = record
|
TGtkCellPixmap* {.final.} = object
|
||||||
`type`*: TGtkCellType
|
`type`*: TGtkCellType
|
||||||
vertical*: gint16
|
vertical*: gint16
|
||||||
horizontal*: gint16
|
horizontal*: gint16
|
||||||
|
|
@ -1053,7 +1053,7 @@ type
|
||||||
mask*: PGdkBitmap
|
mask*: PGdkBitmap
|
||||||
|
|
||||||
PGtkCellPixText* = ptr TGtkCellPixText
|
PGtkCellPixText* = ptr TGtkCellPixText
|
||||||
TGtkCellPixText* = record
|
TGtkCellPixText* {.final.} = object
|
||||||
`type`*: TGtkCellType
|
`type`*: TGtkCellType
|
||||||
vertical*: gint16
|
vertical*: gint16
|
||||||
horizontal*: gint16
|
horizontal*: gint16
|
||||||
|
|
@ -1064,14 +1064,14 @@ type
|
||||||
mask*: PGdkBitmap
|
mask*: PGdkBitmap
|
||||||
|
|
||||||
PGtkCellWidget* = ptr TGtkCellWidget
|
PGtkCellWidget* = ptr TGtkCellWidget
|
||||||
TGtkCellWidget* = record
|
TGtkCellWidget* {.final.} = object
|
||||||
`type`*: TGtkCellType
|
`type`*: TGtkCellType
|
||||||
vertical*: gint16
|
vertical*: gint16
|
||||||
horizontal*: gint16
|
horizontal*: gint16
|
||||||
style*: PGtkStyle
|
style*: PGtkStyle
|
||||||
widget*: PGtkWidget
|
widget*: PGtkWidget
|
||||||
|
|
||||||
TGtkCell* = record
|
TGtkCell* {.final.} = object
|
||||||
`type`*: TGtkCellType
|
`type`*: TGtkCellType
|
||||||
vertical*: gint16
|
vertical*: gint16
|
||||||
horizontal*: gint16
|
horizontal*: gint16
|
||||||
|
|
@ -1212,7 +1212,7 @@ type
|
||||||
action: TGtkCTreeExpansionType){.cdecl.}
|
action: TGtkCTreeExpansionType){.cdecl.}
|
||||||
|
|
||||||
PGtkCTreeRow* = ptr TGtkCTreeRow
|
PGtkCTreeRow* = ptr TGtkCTreeRow
|
||||||
TGtkCTreeRow* = record
|
TGtkCTreeRow* {.final.} = object
|
||||||
row*: TGtkCListRow
|
row*: TGtkCListRow
|
||||||
parent*: PGtkCTreeNode
|
parent*: PGtkCTreeNode
|
||||||
sibling*: PGtkCTreeNode
|
sibling*: PGtkCTreeNode
|
||||||
|
|
@ -1224,7 +1224,7 @@ type
|
||||||
level*: guint16
|
level*: guint16
|
||||||
GtkCTreeRow_flag0*: guint16
|
GtkCTreeRow_flag0*: guint16
|
||||||
|
|
||||||
TGtkCTreeNode* = record
|
TGtkCTreeNode* {.final.} = object
|
||||||
list*: TGList
|
list*: TGList
|
||||||
|
|
||||||
PGtkDrawingArea* = ptr TGtkDrawingArea
|
PGtkDrawingArea* = ptr TGtkDrawingArea
|
||||||
|
|
@ -1479,7 +1479,7 @@ type
|
||||||
TGtkFixedClass* = object of TGtkContainerClass
|
TGtkFixedClass* = object of TGtkContainerClass
|
||||||
|
|
||||||
PGtkFixedChild* = ptr TGtkFixedChild
|
PGtkFixedChild* = ptr TGtkFixedChild
|
||||||
TGtkFixedChild* = record
|
TGtkFixedChild* {.final.} = object
|
||||||
widget*: PGtkWidget
|
widget*: PGtkWidget
|
||||||
x*: gint
|
x*: gint
|
||||||
y*: gint
|
y*: gint
|
||||||
|
|
@ -1632,7 +1632,7 @@ type
|
||||||
gtk_reserved363: proc (){.cdecl.}
|
gtk_reserved363: proc (){.cdecl.}
|
||||||
gtk_reserved364: proc (){.cdecl.}
|
gtk_reserved364: proc (){.cdecl.}
|
||||||
|
|
||||||
TGtkRulerMetric* = record
|
TGtkRulerMetric* {.final.} = object
|
||||||
metric_name*: cstring
|
metric_name*: cstring
|
||||||
abbrev*: cstring
|
abbrev*: cstring
|
||||||
pixels_per_unit*: gdouble
|
pixels_per_unit*: gdouble
|
||||||
|
|
@ -1657,7 +1657,7 @@ type
|
||||||
TGtkSettingsClass* = object of TGObjectClass
|
TGtkSettingsClass* = object of TGObjectClass
|
||||||
|
|
||||||
PGtkSettingsValue* = ptr TGtkSettingsValue
|
PGtkSettingsValue* = ptr TGtkSettingsValue
|
||||||
TGtkSettingsValue* = record
|
TGtkSettingsValue* {.final.} = object
|
||||||
origin*: cstring
|
origin*: cstring
|
||||||
value*: TGValue
|
value*: TGValue
|
||||||
|
|
||||||
|
|
@ -1708,7 +1708,7 @@ type
|
||||||
GTK_RC_TOKEN_IM_MODULE_FILE, GTK_RC_TOKEN_STOCK, GTK_RC_TOKEN_LTR,
|
GTK_RC_TOKEN_IM_MODULE_FILE, GTK_RC_TOKEN_STOCK, GTK_RC_TOKEN_LTR,
|
||||||
GTK_RC_TOKEN_RTL, GTK_RC_TOKEN_LAST
|
GTK_RC_TOKEN_RTL, GTK_RC_TOKEN_LAST
|
||||||
PGtkRcProperty* = ptr TGtkRcProperty
|
PGtkRcProperty* = ptr TGtkRcProperty
|
||||||
TGtkRcProperty* = record
|
TGtkRcProperty* {.final.} = object
|
||||||
type_name*: TGQuark
|
type_name*: TGQuark
|
||||||
property_name*: TGQuark
|
property_name*: TGQuark
|
||||||
origin*: cstring
|
origin*: cstring
|
||||||
|
|
@ -1877,7 +1877,7 @@ type
|
||||||
gtk_reserved3812: proc (){.cdecl.}
|
gtk_reserved3812: proc (){.cdecl.}
|
||||||
|
|
||||||
PGtkBorder* = ptr TGtkBorder
|
PGtkBorder* = ptr TGtkBorder
|
||||||
TGtkBorder* = record
|
TGtkBorder* {.final.} = object
|
||||||
left*: gint
|
left*: gint
|
||||||
right*: gint
|
right*: gint
|
||||||
top*: gint
|
top*: gint
|
||||||
|
|
@ -1978,27 +1978,27 @@ type
|
||||||
|
|
||||||
PGtkIconSet* = pointer
|
PGtkIconSet* = pointer
|
||||||
PGtkImagePixmapData* = ptr TGtkImagePixmapData
|
PGtkImagePixmapData* = ptr TGtkImagePixmapData
|
||||||
TGtkImagePixmapData* = record
|
TGtkImagePixmapData* {.final.} = object
|
||||||
pixmap*: PGdkPixmap
|
pixmap*: PGdkPixmap
|
||||||
|
|
||||||
PGtkImageImageData* = ptr TGtkImageImageData
|
PGtkImageImageData* = ptr TGtkImageImageData
|
||||||
TGtkImageImageData* = record
|
TGtkImageImageData* {.final.} = object
|
||||||
image*: PGdkImage
|
image*: PGdkImage
|
||||||
|
|
||||||
PGtkImagePixbufData* = ptr TGtkImagePixbufData
|
PGtkImagePixbufData* = ptr TGtkImagePixbufData
|
||||||
TGtkImagePixbufData* = record
|
TGtkImagePixbufData* {.final.} = object
|
||||||
pixbuf*: PGdkPixbuf
|
pixbuf*: PGdkPixbuf
|
||||||
|
|
||||||
PGtkImageStockData* = ptr TGtkImageStockData
|
PGtkImageStockData* = ptr TGtkImageStockData
|
||||||
TGtkImageStockData* = record
|
TGtkImageStockData* {.final.} = object
|
||||||
stock_id*: cstring
|
stock_id*: cstring
|
||||||
|
|
||||||
PGtkImageIconSetData* = ptr TGtkImageIconSetData
|
PGtkImageIconSetData* = ptr TGtkImageIconSetData
|
||||||
TGtkImageIconSetData* = record
|
TGtkImageIconSetData* {.final.} = object
|
||||||
icon_set*: PGtkIconSet
|
icon_set*: PGtkIconSet
|
||||||
|
|
||||||
PGtkImageAnimationData* = ptr TGtkImageAnimationData
|
PGtkImageAnimationData* = ptr TGtkImageAnimationData
|
||||||
TGtkImageAnimationData* = record
|
TGtkImageAnimationData* {.final.} = object
|
||||||
anim*: PGdkPixbufAnimation
|
anim*: PGdkPixbufAnimation
|
||||||
iter*: PGdkPixbufAnimationIter
|
iter*: PGdkPixbufAnimationIter
|
||||||
frame_timeout*: guint
|
frame_timeout*: guint
|
||||||
|
|
@ -2111,7 +2111,7 @@ type
|
||||||
gtk_reserved474: proc (){.cdecl.}
|
gtk_reserved474: proc (){.cdecl.}
|
||||||
|
|
||||||
PGtkItemFactoryEntry* = ptr TGtkItemFactoryEntry
|
PGtkItemFactoryEntry* = ptr TGtkItemFactoryEntry
|
||||||
TGtkItemFactoryEntry* = record
|
TGtkItemFactoryEntry* {.final.} = object
|
||||||
path*: cstring
|
path*: cstring
|
||||||
accelerator*: cstring
|
accelerator*: cstring
|
||||||
callback*: TGtkItemFactoryCallback
|
callback*: TGtkItemFactoryCallback
|
||||||
|
|
@ -2120,7 +2120,7 @@ type
|
||||||
extra_data*: gconstpointer
|
extra_data*: gconstpointer
|
||||||
|
|
||||||
PGtkItemFactoryItem* = ptr TGtkItemFactoryItem
|
PGtkItemFactoryItem* = ptr TGtkItemFactoryItem
|
||||||
TGtkItemFactoryItem* = record
|
TGtkItemFactoryItem* {.final.} = object
|
||||||
path*: cstring
|
path*: cstring
|
||||||
widgets*: PGSList
|
widgets*: PGSList
|
||||||
|
|
||||||
|
|
@ -2173,7 +2173,7 @@ type
|
||||||
cdecl.}
|
cdecl.}
|
||||||
PGtkTreeModelFlags* = ptr TGtkTreeModelFlags
|
PGtkTreeModelFlags* = ptr TGtkTreeModelFlags
|
||||||
TGtkTreeModelFlags* = int32
|
TGtkTreeModelFlags* = int32
|
||||||
TGtkTreeIter* = record
|
TGtkTreeIter* {.final.} = object
|
||||||
stamp*: gint
|
stamp*: gint
|
||||||
user_data*: gpointer
|
user_data*: gpointer
|
||||||
user_data2*: gpointer
|
user_data2*: gpointer
|
||||||
|
|
@ -2435,12 +2435,12 @@ type
|
||||||
GtkPreview_flag0*: guint16
|
GtkPreview_flag0*: guint16
|
||||||
|
|
||||||
PGtkPreviewInfo* = ptr TGtkPreviewInfo
|
PGtkPreviewInfo* = ptr TGtkPreviewInfo
|
||||||
TGtkPreviewInfo* = record
|
TGtkPreviewInfo* {.final.} = object
|
||||||
lookup*: Pguchar
|
lookup*: Pguchar
|
||||||
gamma*: gdouble
|
gamma*: gdouble
|
||||||
|
|
||||||
PGtkDitherInfo* = ptr TGtkDitherInfo
|
PGtkDitherInfo* = ptr TGtkDitherInfo
|
||||||
TGtkDitherInfo* = record
|
TGtkDitherInfo* {.final.} = object
|
||||||
c*: array[0..3, guchar]
|
c*: array[0..3, guchar]
|
||||||
|
|
||||||
PGtkPreviewClass* = ptr TGtkPreviewClass
|
PGtkPreviewClass* = ptr TGtkPreviewClass
|
||||||
|
|
@ -2533,7 +2533,7 @@ type
|
||||||
gtk_reserved603: proc (){.cdecl.}
|
gtk_reserved603: proc (){.cdecl.}
|
||||||
gtk_reserved604: proc (){.cdecl.}
|
gtk_reserved604: proc (){.cdecl.}
|
||||||
|
|
||||||
TGtkSelectionData* = record
|
TGtkSelectionData* {.final.} = object
|
||||||
selection*: TGdkAtom
|
selection*: TGdkAtom
|
||||||
target*: TGdkAtom
|
target*: TGdkAtom
|
||||||
thetype*: TGdkAtom
|
thetype*: TGdkAtom
|
||||||
|
|
@ -2543,18 +2543,18 @@ type
|
||||||
display*: PGdkDisplay
|
display*: PGdkDisplay
|
||||||
|
|
||||||
PGtkTargetEntry* = ptr TGtkTargetEntry
|
PGtkTargetEntry* = ptr TGtkTargetEntry
|
||||||
TGtkTargetEntry* = record
|
TGtkTargetEntry* {.final.} = object
|
||||||
target*: cstring
|
target*: cstring
|
||||||
flags*: guint
|
flags*: guint
|
||||||
info*: guint
|
info*: guint
|
||||||
|
|
||||||
PGtkTargetList* = ptr TGtkTargetList
|
PGtkTargetList* = ptr TGtkTargetList
|
||||||
TGtkTargetList* = record
|
TGtkTargetList* {.final.} = object
|
||||||
list*: PGList
|
list*: PGList
|
||||||
ref_count*: guint
|
ref_count*: guint
|
||||||
|
|
||||||
PGtkTargetPair* = ptr TGtkTargetPair
|
PGtkTargetPair* = ptr TGtkTargetPair
|
||||||
TGtkTargetPair* = record
|
TGtkTargetPair* {.final.} = object
|
||||||
target*: TGdkAtom
|
target*: TGdkAtom
|
||||||
flags*: guint
|
flags*: guint
|
||||||
info*: guint
|
info*: guint
|
||||||
|
|
@ -2635,7 +2635,7 @@ type
|
||||||
gtk_reserved634: proc (){.cdecl.}
|
gtk_reserved634: proc (){.cdecl.}
|
||||||
|
|
||||||
PGtkStockItem* = ptr TGtkStockItem
|
PGtkStockItem* = ptr TGtkStockItem
|
||||||
TGtkStockItem* = record
|
TGtkStockItem* {.final.} = object
|
||||||
stock_id*: cstring
|
stock_id*: cstring
|
||||||
label*: cstring
|
label*: cstring
|
||||||
modifier*: TGdkModifierType
|
modifier*: TGdkModifierType
|
||||||
|
|
@ -2681,7 +2681,7 @@ type
|
||||||
TGtkTableClass* = object of TGtkContainerClass
|
TGtkTableClass* = object of TGtkContainerClass
|
||||||
|
|
||||||
PGtkTableChild* = ptr TGtkTableChild
|
PGtkTableChild* = ptr TGtkTableChild
|
||||||
TGtkTableChild* = record
|
TGtkTableChild* {.final.} = object
|
||||||
widget*: PGtkWidget
|
widget*: PGtkWidget
|
||||||
left_attach*: guint16
|
left_attach*: guint16
|
||||||
right_attach*: guint16
|
right_attach*: guint16
|
||||||
|
|
@ -2691,7 +2691,7 @@ type
|
||||||
ypadding*: guint16
|
ypadding*: guint16
|
||||||
GtkTableChild_flag0*: guint16
|
GtkTableChild_flag0*: guint16
|
||||||
|
|
||||||
TGtkTableRowCol* = record
|
TGtkTableRowCol* {.final.} = object
|
||||||
requisition*: guint16
|
requisition*: guint16
|
||||||
allocation*: guint16
|
allocation*: guint16
|
||||||
spacing*: guint16
|
spacing*: guint16
|
||||||
|
|
@ -2710,7 +2710,7 @@ type
|
||||||
|
|
||||||
PGtkTextFont* = pointer
|
PGtkTextFont* = pointer
|
||||||
PGtkPropertyMark* = ptr TGtkPropertyMark
|
PGtkPropertyMark* = ptr TGtkPropertyMark
|
||||||
TGtkPropertyMark* = record
|
TGtkPropertyMark* {.final.} = object
|
||||||
`property`*: PGList
|
`property`*: PGList
|
||||||
offset*: guint
|
offset*: guint
|
||||||
index*: guint
|
index*: guint
|
||||||
|
|
@ -2764,7 +2764,7 @@ type
|
||||||
PGtkTextSearchFlags* = ptr TGtkTextSearchFlags
|
PGtkTextSearchFlags* = ptr TGtkTextSearchFlags
|
||||||
TGtkTextSearchFlags* = int32
|
TGtkTextSearchFlags* = int32
|
||||||
PGtkTextIter* = ptr TGtkTextIter
|
PGtkTextIter* = ptr TGtkTextIter
|
||||||
TGtkTextIter* = record
|
TGtkTextIter* {.final.} = object
|
||||||
dummy1*: gpointer
|
dummy1*: gpointer
|
||||||
dummy2*: gpointer
|
dummy2*: gpointer
|
||||||
dummy3*: gint
|
dummy3*: gint
|
||||||
|
|
@ -2802,7 +2802,7 @@ type
|
||||||
gtk_reserved664: proc (){.cdecl.}
|
gtk_reserved664: proc (){.cdecl.}
|
||||||
|
|
||||||
PGtkTextAppearance* = ptr TGtkTextAppearance
|
PGtkTextAppearance* = ptr TGtkTextAppearance
|
||||||
TGtkTextAppearance* = record
|
TGtkTextAppearance* {.final.} = object
|
||||||
bg_color*: TGdkColor
|
bg_color*: TGdkColor
|
||||||
fg_color*: TGdkColor
|
fg_color*: TGdkColor
|
||||||
bg_stipple*: PGdkBitmap
|
bg_stipple*: PGdkBitmap
|
||||||
|
|
@ -2811,7 +2811,7 @@ type
|
||||||
padding1*: gpointer
|
padding1*: gpointer
|
||||||
flag0*: guint16
|
flag0*: guint16
|
||||||
|
|
||||||
TGtkTextAttributes* = record
|
TGtkTextAttributes* {.final.} = object
|
||||||
refcount*: guint
|
refcount*: guint
|
||||||
appearance*: TGtkTextAppearance
|
appearance*: TGtkTextAppearance
|
||||||
justification*: TGtkJustification
|
justification*: TGtkJustification
|
||||||
|
|
@ -2860,7 +2860,7 @@ type
|
||||||
gtk_reserved4: proc (){.cdecl.}
|
gtk_reserved4: proc (){.cdecl.}
|
||||||
|
|
||||||
PGtkTextMarkBody* = ptr TGtkTextMarkBody
|
PGtkTextMarkBody* = ptr TGtkTextMarkBody
|
||||||
TGtkTextMarkBody* = record
|
TGtkTextMarkBody* {.final.} = object
|
||||||
obj*: PGtkTextMark
|
obj*: PGtkTextMark
|
||||||
name*: cstring
|
name*: cstring
|
||||||
tree*: PGtkTextBTree
|
tree*: PGtkTextBTree
|
||||||
|
|
@ -2879,11 +2879,11 @@ type
|
||||||
gtk_reserved4: proc (){.cdecl.}
|
gtk_reserved4: proc (){.cdecl.}
|
||||||
|
|
||||||
PGtkTextPixbuf* = ptr TGtkTextPixbuf
|
PGtkTextPixbuf* = ptr TGtkTextPixbuf
|
||||||
TGtkTextPixbuf* = record
|
TGtkTextPixbuf* {.final.} = object
|
||||||
pixbuf*: PGdkPixbuf
|
pixbuf*: PGdkPixbuf
|
||||||
|
|
||||||
PGtkTextChildBody* = ptr TGtkTextChildBody
|
PGtkTextChildBody* = ptr TGtkTextChildBody
|
||||||
TGtkTextChildBody* = record
|
TGtkTextChildBody* {.final.} = object
|
||||||
obj*: PGtkTextChildAnchor
|
obj*: PGtkTextChildAnchor
|
||||||
widgets*: PGSList
|
widgets*: PGSList
|
||||||
tree*: PGtkTextBTree
|
tree*: PGtkTextBTree
|
||||||
|
|
@ -2892,17 +2892,17 @@ type
|
||||||
PGtkTextLineSegment* = ptr TGtkTextLineSegment
|
PGtkTextLineSegment* = ptr TGtkTextLineSegment
|
||||||
PGtkTextLineSegmentClass* = ptr TGtkTextLineSegmentClass
|
PGtkTextLineSegmentClass* = ptr TGtkTextLineSegmentClass
|
||||||
PGtkTextTagInfo* = ptr TGtkTextTagInfo
|
PGtkTextTagInfo* = ptr TGtkTextTagInfo
|
||||||
TGtkTextTagInfo* = record
|
TGtkTextTagInfo* {.final.} = object
|
||||||
tag*: PGtkTextTag
|
tag*: PGtkTextTag
|
||||||
tag_root*: PGtkTextBTreeNode
|
tag_root*: PGtkTextBTreeNode
|
||||||
toggle_count*: gint
|
toggle_count*: gint
|
||||||
|
|
||||||
PGtkTextToggleBody* = ptr TGtkTextToggleBody
|
PGtkTextToggleBody* = ptr TGtkTextToggleBody
|
||||||
TGtkTextToggleBody* = record
|
TGtkTextToggleBody* {.final.} = object
|
||||||
info*: PGtkTextTagInfo
|
info*: PGtkTextTagInfo
|
||||||
inNodeCounts*: gboolean
|
inNodeCounts*: gboolean
|
||||||
|
|
||||||
TGtkTextLineSegment* = record
|
TGtkTextLineSegment* {.final.} = object
|
||||||
`type`*: PGtkTextLineSegmentClass
|
`type`*: PGtkTextLineSegmentClass
|
||||||
next*: PGtkTextLineSegment
|
next*: PGtkTextLineSegment
|
||||||
char_count*: int32
|
char_count*: int32
|
||||||
|
|
@ -2919,7 +2919,7 @@ type
|
||||||
line: PGtkTextLine){.cdecl.}
|
line: PGtkTextLine){.cdecl.}
|
||||||
TGtkTextSegCheckFunc* = proc (seg: PGtkTextLineSegment, line: PGtkTextLine){.
|
TGtkTextSegCheckFunc* = proc (seg: PGtkTextLineSegment, line: PGtkTextLine){.
|
||||||
cdecl.}
|
cdecl.}
|
||||||
TGtkTextLineSegmentClass* = record
|
TGtkTextLineSegmentClass* {.final.} = object
|
||||||
name*: cstring
|
name*: cstring
|
||||||
leftGravity*: gboolean
|
leftGravity*: gboolean
|
||||||
splitFunc*: TGtkTextSegSplitFunc
|
splitFunc*: TGtkTextSegSplitFunc
|
||||||
|
|
@ -2929,13 +2929,13 @@ type
|
||||||
checkFunc*: TGtkTextSegCheckFunc
|
checkFunc*: TGtkTextSegCheckFunc
|
||||||
|
|
||||||
PGtkTextLineData* = ptr TGtkTextLineData
|
PGtkTextLineData* = ptr TGtkTextLineData
|
||||||
TGtkTextLineData* = record
|
TGtkTextLineData* {.final.} = object
|
||||||
view_id*: gpointer
|
view_id*: gpointer
|
||||||
next*: PGtkTextLineData
|
next*: PGtkTextLineData
|
||||||
height*: gint
|
height*: gint
|
||||||
flag0*: int32
|
flag0*: int32
|
||||||
|
|
||||||
TGtkTextLine* = record
|
TGtkTextLine* {.final.} = object
|
||||||
parent*: PGtkTextBTreeNode
|
parent*: PGtkTextBTreeNode
|
||||||
next*: PGtkTextLine
|
next*: PGtkTextLine
|
||||||
segments*: PGtkTextLineSegment
|
segments*: PGtkTextLineSegment
|
||||||
|
|
@ -3020,18 +3020,18 @@ type
|
||||||
gtk_reserved4: proc (){.cdecl.}
|
gtk_reserved4: proc (){.cdecl.}
|
||||||
|
|
||||||
PGtkTextAttrAppearance* = ptr TGtkTextAttrAppearance
|
PGtkTextAttrAppearance* = ptr TGtkTextAttrAppearance
|
||||||
TGtkTextAttrAppearance* = record
|
TGtkTextAttrAppearance* {.final.} = object
|
||||||
attr*: TPangoAttribute
|
attr*: TPangoAttribute
|
||||||
appearance*: TGtkTextAppearance
|
appearance*: TGtkTextAppearance
|
||||||
|
|
||||||
PGtkTextCursorDisplay* = ptr TGtkTextCursorDisplay
|
PGtkTextCursorDisplay* = ptr TGtkTextCursorDisplay
|
||||||
TGtkTextCursorDisplay* = record
|
TGtkTextCursorDisplay* {.final.} = object
|
||||||
x*: gint
|
x*: gint
|
||||||
y*: gint
|
y*: gint
|
||||||
height*: gint
|
height*: gint
|
||||||
flag0*: guint16
|
flag0*: guint16
|
||||||
|
|
||||||
TGtkTextLineDisplay* = record
|
TGtkTextLineDisplay* {.final.} = object
|
||||||
layout*: PPangoLayout
|
layout*: PPangoLayout
|
||||||
cursors*: PGSList
|
cursors*: PGSList
|
||||||
shaped_objects*: PGSList
|
shaped_objects*: PGSList
|
||||||
|
|
@ -3152,7 +3152,7 @@ type
|
||||||
|
|
||||||
PGtkTooltips* = ptr TGtkTooltips
|
PGtkTooltips* = ptr TGtkTooltips
|
||||||
PGtkTooltipsData* = ptr TGtkTooltipsData
|
PGtkTooltipsData* = ptr TGtkTooltipsData
|
||||||
TGtkTooltipsData* = record
|
TGtkTooltipsData* {.final.} = object
|
||||||
tooltips*: PGtkTooltips
|
tooltips*: PGtkTooltips
|
||||||
widget*: PGtkWidget
|
widget*: PGtkWidget
|
||||||
tip_text*: cstring
|
tip_text*: cstring
|
||||||
|
|
@ -3184,7 +3184,7 @@ type
|
||||||
TGtkToolbarSpaceStyle* = enum
|
TGtkToolbarSpaceStyle* = enum
|
||||||
GTK_TOOLBAR_SPACE_EMPTY, GTK_TOOLBAR_SPACE_LINE
|
GTK_TOOLBAR_SPACE_EMPTY, GTK_TOOLBAR_SPACE_LINE
|
||||||
PGtkToolbarChild* = ptr TGtkToolbarChild
|
PGtkToolbarChild* = ptr TGtkToolbarChild
|
||||||
TGtkToolbarChild* = record
|
TGtkToolbarChild* {.final.} = object
|
||||||
`type`*: TGtkToolbarChildType
|
`type`*: TGtkToolbarChildType
|
||||||
widget*: PGtkWidget
|
widget*: PGtkWidget
|
||||||
icon*: PGtkWidget
|
icon*: PGtkWidget
|
||||||
|
|
@ -3365,13 +3365,13 @@ type
|
||||||
PGtkRBNode* = ptr TGtkRBNode
|
PGtkRBNode* = ptr TGtkRBNode
|
||||||
TGtkRBTreeTraverseFunc* = proc (tree: PGtkRBTree, node: PGtkRBNode,
|
TGtkRBTreeTraverseFunc* = proc (tree: PGtkRBTree, node: PGtkRBNode,
|
||||||
data: gpointer){.cdecl.}
|
data: gpointer){.cdecl.}
|
||||||
TGtkRBTree* = record
|
TGtkRBTree* {.final.} = object
|
||||||
root*: PGtkRBNode
|
root*: PGtkRBNode
|
||||||
`nil`*: PGtkRBNode
|
`nil`*: PGtkRBNode
|
||||||
parent_tree*: PGtkRBTree
|
parent_tree*: PGtkRBTree
|
||||||
parent_node*: PGtkRBNode
|
parent_node*: PGtkRBNode
|
||||||
|
|
||||||
TGtkRBNode* = record
|
TGtkRBNode* {.final.} = object
|
||||||
flag0*: guint16
|
flag0*: guint16
|
||||||
left*: PGtkRBNode
|
left*: PGtkRBNode
|
||||||
right*: PGtkRBNode
|
right*: PGtkRBNode
|
||||||
|
|
@ -3386,14 +3386,14 @@ type
|
||||||
TGtkTreeViewSearchDialogPositionFunc* = proc (tree_view: PGtkTreeView,
|
TGtkTreeViewSearchDialogPositionFunc* = proc (tree_view: PGtkTreeView,
|
||||||
search_dialog: PGtkWidget){.cdecl.}
|
search_dialog: PGtkWidget){.cdecl.}
|
||||||
PGtkTreeViewColumnReorder* = ptr TGtkTreeViewColumnReorder
|
PGtkTreeViewColumnReorder* = ptr TGtkTreeViewColumnReorder
|
||||||
TGtkTreeViewColumnReorder* = record
|
TGtkTreeViewColumnReorder* {.final.} = object
|
||||||
left_align*: gint
|
left_align*: gint
|
||||||
right_align*: gint
|
right_align*: gint
|
||||||
left_column*: PGtkTreeViewColumn
|
left_column*: PGtkTreeViewColumn
|
||||||
right_column*: PGtkTreeViewColumn
|
right_column*: PGtkTreeViewColumn
|
||||||
|
|
||||||
PGtkTreeViewPrivate* = ptr TGtkTreeViewPrivate
|
PGtkTreeViewPrivate* = ptr TGtkTreeViewPrivate
|
||||||
TGtkTreeViewPrivate* = record
|
TGtkTreeViewPrivate* {.final.} = object
|
||||||
model*: PGtkTreeModel
|
model*: PGtkTreeModel
|
||||||
flags*: guint
|
flags*: guint
|
||||||
tree*: PGtkRBTree
|
tree*: PGtkRBTree
|
||||||
|
|
@ -11304,96 +11304,127 @@ proc GTK_FUNDAMENTAL_TYPE*(thetype: GType): GType =
|
||||||
result = G_TYPE_FUNDAMENTAL(thetype)
|
result = G_TYPE_FUNDAMENTAL(thetype)
|
||||||
|
|
||||||
proc GTK_VALUE_CHAR*(a: TGtkArg): gchar =
|
proc GTK_VALUE_CHAR*(a: TGtkArg): gchar =
|
||||||
|
var a = a
|
||||||
Result = cast[ptr gchar](addr(a.d))^
|
Result = cast[ptr gchar](addr(a.d))^
|
||||||
|
|
||||||
proc GTK_VALUE_UCHAR*(a: TGtkArg): guchar =
|
proc GTK_VALUE_UCHAR*(a: TGtkArg): guchar =
|
||||||
|
var a = a
|
||||||
Result = cast[ptr guchar](addr(a.d))^
|
Result = cast[ptr guchar](addr(a.d))^
|
||||||
|
|
||||||
proc GTK_VALUE_BOOL*(a: TGtkArg): gboolean =
|
proc GTK_VALUE_BOOL*(a: TGtkArg): gboolean =
|
||||||
|
var a = a
|
||||||
Result = cast[ptr gboolean](addr(a.d))^
|
Result = cast[ptr gboolean](addr(a.d))^
|
||||||
|
|
||||||
proc GTK_VALUE_INT*(a: TGtkArg): gint =
|
proc GTK_VALUE_INT*(a: TGtkArg): gint =
|
||||||
|
var a = a
|
||||||
Result = cast[ptr gint](addr(a.d))^
|
Result = cast[ptr gint](addr(a.d))^
|
||||||
|
|
||||||
proc GTK_VALUE_UINT*(a: TGtkArg): guint =
|
proc GTK_VALUE_UINT*(a: TGtkArg): guint =
|
||||||
|
var a = a
|
||||||
Result = cast[ptr guint](addr(a.d))^
|
Result = cast[ptr guint](addr(a.d))^
|
||||||
|
|
||||||
proc GTK_VALUE_LONG*(a: TGtkArg): glong =
|
proc GTK_VALUE_LONG*(a: TGtkArg): glong =
|
||||||
|
var a = a
|
||||||
Result = cast[ptr glong](addr(a.d))^
|
Result = cast[ptr glong](addr(a.d))^
|
||||||
|
|
||||||
proc GTK_VALUE_ULONG*(a: TGtkArg): gulong =
|
proc GTK_VALUE_ULONG*(a: TGtkArg): gulong =
|
||||||
|
var a = a
|
||||||
Result = cast[ptr gulong](addr(a.d))^
|
Result = cast[ptr gulong](addr(a.d))^
|
||||||
|
|
||||||
proc GTK_VALUE_FLOAT*(a: TGtkArg): gfloat =
|
proc GTK_VALUE_FLOAT*(a: TGtkArg): gfloat =
|
||||||
|
var a = a
|
||||||
Result = cast[ptr gfloat](addr(a.d))^
|
Result = cast[ptr gfloat](addr(a.d))^
|
||||||
|
|
||||||
proc GTK_VALUE_DOUBLE*(a: TGtkArg): gdouble =
|
proc GTK_VALUE_DOUBLE*(a: TGtkArg): gdouble =
|
||||||
|
var a = a
|
||||||
Result = cast[ptr gdouble](addr(a.d))^
|
Result = cast[ptr gdouble](addr(a.d))^
|
||||||
|
|
||||||
proc GTK_VALUE_STRING*(a: TGtkArg): cstring =
|
proc GTK_VALUE_STRING*(a: TGtkArg): cstring =
|
||||||
|
var a = a
|
||||||
Result = cast[ptr cstring](addr(a.d))^
|
Result = cast[ptr cstring](addr(a.d))^
|
||||||
|
|
||||||
proc GTK_VALUE_ENUM*(a: TGtkArg): gint =
|
proc GTK_VALUE_ENUM*(a: TGtkArg): gint =
|
||||||
|
var a = a
|
||||||
Result = cast[ptr gint](addr(a.d))^
|
Result = cast[ptr gint](addr(a.d))^
|
||||||
|
|
||||||
proc GTK_VALUE_FLAGS*(a: TGtkArg): guint =
|
proc GTK_VALUE_FLAGS*(a: TGtkArg): guint =
|
||||||
|
var a = a
|
||||||
Result = cast[ptr guint](addr(a.d))^
|
Result = cast[ptr guint](addr(a.d))^
|
||||||
|
|
||||||
proc GTK_VALUE_BOXED*(a: TGtkArg): gpointer =
|
proc GTK_VALUE_BOXED*(a: TGtkArg): gpointer =
|
||||||
|
var a = a
|
||||||
Result = cast[ptr gpointer](addr(a.d))^
|
Result = cast[ptr gpointer](addr(a.d))^
|
||||||
|
|
||||||
proc GTK_VALUE_OBJECT*(a: TGtkArg): PGtkObject =
|
proc GTK_VALUE_OBJECT*(a: TGtkArg): PGtkObject =
|
||||||
|
var a = a
|
||||||
Result = cast[ptr PGtkObject](addr(a.d))^
|
Result = cast[ptr PGtkObject](addr(a.d))^
|
||||||
|
|
||||||
proc GTK_VALUE_POINTER*(a: TGtkArg): GPointer =
|
proc GTK_VALUE_POINTER*(a: TGtkArg): GPointer =
|
||||||
|
var a = a
|
||||||
Result = cast[ptr gpointer](addr(a.d))^
|
Result = cast[ptr gpointer](addr(a.d))^
|
||||||
|
|
||||||
proc GTK_VALUE_SIGNAL*(a: TGtkArg): TGtkArgSignalData =
|
proc GTK_VALUE_SIGNAL*(a: TGtkArg): TGtkArgSignalData =
|
||||||
|
var a = a
|
||||||
Result = cast[ptr TGtkArgSignalData](addr(a.d))^
|
Result = cast[ptr TGtkArgSignalData](addr(a.d))^
|
||||||
|
|
||||||
proc GTK_RETLOC_CHAR*(a: TGtkArg): cstring =
|
proc GTK_RETLOC_CHAR*(a: TGtkArg): cstring =
|
||||||
|
var a = a
|
||||||
Result = cast[ptr cstring](addr(a.d))^
|
Result = cast[ptr cstring](addr(a.d))^
|
||||||
|
|
||||||
proc GTK_RETLOC_UCHAR*(a: TGtkArg): Pguchar =
|
proc GTK_RETLOC_UCHAR*(a: TGtkArg): Pguchar =
|
||||||
|
var a = a
|
||||||
Result = cast[ptr pguchar](addr(a.d))^
|
Result = cast[ptr pguchar](addr(a.d))^
|
||||||
|
|
||||||
proc GTK_RETLOC_BOOL*(a: TGtkArg): Pgboolean =
|
proc GTK_RETLOC_BOOL*(a: TGtkArg): Pgboolean =
|
||||||
|
var a = a
|
||||||
Result = cast[ptr pgboolean](addr(a.d))^
|
Result = cast[ptr pgboolean](addr(a.d))^
|
||||||
|
|
||||||
proc GTK_RETLOC_INT*(a: TGtkArg): Pgint =
|
proc GTK_RETLOC_INT*(a: TGtkArg): Pgint =
|
||||||
|
var a = a
|
||||||
Result = cast[ptr pgint](addr(a.d))^
|
Result = cast[ptr pgint](addr(a.d))^
|
||||||
|
|
||||||
proc GTK_RETLOC_UINT*(a: TGtkArg): Pguint =
|
proc GTK_RETLOC_UINT*(a: TGtkArg): Pguint =
|
||||||
|
var a = a
|
||||||
Result = cast[ptr pguint](addr(a.d))^
|
Result = cast[ptr pguint](addr(a.d))^
|
||||||
|
|
||||||
proc GTK_RETLOC_LONG*(a: TGtkArg): Pglong =
|
proc GTK_RETLOC_LONG*(a: TGtkArg): Pglong =
|
||||||
|
var a = a
|
||||||
Result = cast[ptr pglong](addr(a.d))^
|
Result = cast[ptr pglong](addr(a.d))^
|
||||||
|
|
||||||
proc GTK_RETLOC_ULONG*(a: TGtkArg): Pgulong =
|
proc GTK_RETLOC_ULONG*(a: TGtkArg): Pgulong =
|
||||||
|
var a = a
|
||||||
Result = cast[ptr pgulong](addr(a.d))^
|
Result = cast[ptr pgulong](addr(a.d))^
|
||||||
|
|
||||||
proc GTK_RETLOC_FLOAT*(a: TGtkArg): Pgfloat =
|
proc GTK_RETLOC_FLOAT*(a: TGtkArg): Pgfloat =
|
||||||
|
var a = a
|
||||||
Result = cast[ptr pgfloat](addr(a.d))^
|
Result = cast[ptr pgfloat](addr(a.d))^
|
||||||
|
|
||||||
proc GTK_RETLOC_DOUBLE*(a: TGtkArg): Pgdouble =
|
proc GTK_RETLOC_DOUBLE*(a: TGtkArg): Pgdouble =
|
||||||
|
var a = a
|
||||||
Result = cast[ptr pgdouble](addr(a.d))^
|
Result = cast[ptr pgdouble](addr(a.d))^
|
||||||
|
|
||||||
proc GTK_RETLOC_STRING*(a: TGtkArg): Ppgchar =
|
proc GTK_RETLOC_STRING*(a: TGtkArg): Ppgchar =
|
||||||
|
var a = a
|
||||||
Result = cast[ptr Ppgchar](addr(a.d))^
|
Result = cast[ptr Ppgchar](addr(a.d))^
|
||||||
|
|
||||||
proc GTK_RETLOC_ENUM*(a: TGtkArg): Pgint =
|
proc GTK_RETLOC_ENUM*(a: TGtkArg): Pgint =
|
||||||
|
var a = a
|
||||||
Result = cast[ptr Pgint](addr(a.d))^
|
Result = cast[ptr Pgint](addr(a.d))^
|
||||||
|
|
||||||
proc GTK_RETLOC_FLAGS*(a: TGtkArg): Pguint =
|
proc GTK_RETLOC_FLAGS*(a: TGtkArg): Pguint =
|
||||||
|
var a = a
|
||||||
Result = cast[ptr pguint](addr(a.d))^
|
Result = cast[ptr pguint](addr(a.d))^
|
||||||
|
|
||||||
proc GTK_RETLOC_BOXED*(a: TGtkArg): Pgpointer =
|
proc GTK_RETLOC_BOXED*(a: TGtkArg): Pgpointer =
|
||||||
|
var a = a
|
||||||
Result = cast[ptr pgpointer](addr(a.d))^
|
Result = cast[ptr pgpointer](addr(a.d))^
|
||||||
|
|
||||||
proc GTK_RETLOC_OBJECT*(a: TGtkArg): PPGtkObject =
|
proc GTK_RETLOC_OBJECT*(a: TGtkArg): PPGtkObject =
|
||||||
|
var a = a
|
||||||
Result = cast[ptr ppgtkobject](addr(a.d))^
|
Result = cast[ptr ppgtkobject](addr(a.d))^
|
||||||
|
|
||||||
proc GTK_RETLOC_POINTER*(a: TGtkArg): Pgpointer =
|
proc GTK_RETLOC_POINTER*(a: TGtkArg): Pgpointer =
|
||||||
|
var a = a
|
||||||
Result = cast[ptr pgpointer](addr(a.d))^
|
Result = cast[ptr pgpointer](addr(a.d))^
|
||||||
|
|
||||||
proc GTK_TYPE_WIDGET*(): GType =
|
proc GTK_TYPE_WIDGET*(): GType =
|
||||||
|
|
@ -15108,7 +15139,7 @@ proc gtk_signal_handler_pending_by_func*(anObject: PGtkObject, signal_id: guint,
|
||||||
G_SIGNAL_MATCH_DATA)
|
G_SIGNAL_MATCH_DATA)
|
||||||
if not may_be_blocked:
|
if not may_be_blocked:
|
||||||
t = t or cast[int](G_SIGNAL_MATCH_UNBLOCKED)
|
t = t or cast[int](G_SIGNAL_MATCH_UNBLOCKED)
|
||||||
Result = g_signal_handler_find(anObject, t, signal_id, 0, nil, addr(func_),
|
Result = g_signal_handler_find(anObject, t, signal_id, 0, nil, func_,
|
||||||
data) != 0
|
data) != 0
|
||||||
|
|
||||||
proc GTK_TYPE_SIZE_GROUP*(): GType =
|
proc GTK_TYPE_SIZE_GROUP*(): GType =
|
||||||
|
|
@ -17045,7 +17076,7 @@ type
|
||||||
GTK_FILE_FILTER_FILENAME = 1 shl 0, GTK_FILE_FILTER_URI = 1 shl 1,
|
GTK_FILE_FILTER_FILENAME = 1 shl 0, GTK_FILE_FILTER_URI = 1 shl 1,
|
||||||
GTK_FILE_FILTER_DISPLAY_NAME = 1 shl 2, GTK_FILE_FILTER_MIME_TYPE = 1 shl 3
|
GTK_FILE_FILTER_DISPLAY_NAME = 1 shl 2, GTK_FILE_FILTER_MIME_TYPE = 1 shl 3
|
||||||
PGtkFileFilterInfo* = ref TGtkFileFilterInfo
|
PGtkFileFilterInfo* = ref TGtkFileFilterInfo
|
||||||
TGtkFileFilterInfo* = record
|
TGtkFileFilterInfo* {.final.} = object
|
||||||
contains*: TGtkFileFilterFlags
|
contains*: TGtkFileFilterFlags
|
||||||
filename*: cstring
|
filename*: cstring
|
||||||
uri*: cstring
|
uri*: cstring
|
||||||
|
|
|
||||||
|
|
@ -68,12 +68,12 @@ type
|
||||||
exc: PDomException): PDomString{.cdecl.}
|
exc: PDomException): PDomString{.cdecl.}
|
||||||
|
|
||||||
PDomDocument* = ptr TDomDocument
|
PDomDocument* = ptr TDomDocument
|
||||||
TDomDocument* = record
|
TDomDocument* {.final.} = object
|
||||||
parent*: PDomNode
|
parent*: PDomNode
|
||||||
iterators*: PGSList
|
iterators*: PGSList
|
||||||
|
|
||||||
PDomDocumentClass* = ptr TDomDocumentClass
|
PDomDocumentClass* = ptr TDomDocumentClass
|
||||||
TDomDocumentClass* = record
|
TDomDocumentClass* {.final.} = object
|
||||||
parent_class*: PDomNodeClass
|
parent_class*: PDomNodeClass
|
||||||
|
|
||||||
PHtmlFocusIterator* = ptr THtmlFocusIterator
|
PHtmlFocusIterator* = ptr THtmlFocusIterator
|
||||||
|
|
|
||||||
|
|
@ -50,7 +50,7 @@ type
|
||||||
PPangoGlyph* = ptr TPangoGlyph
|
PPangoGlyph* = ptr TPangoGlyph
|
||||||
TPangoGlyph* = guint32
|
TPangoGlyph* = guint32
|
||||||
PPangoRectangle* = ptr TPangoRectangle
|
PPangoRectangle* = ptr TPangoRectangle
|
||||||
TPangoRectangle* = record
|
TPangoRectangle* {.final.} = object
|
||||||
x*: int32
|
x*: int32
|
||||||
y*: int32
|
y*: int32
|
||||||
width*: int32
|
width*: int32
|
||||||
|
|
@ -61,7 +61,7 @@ type
|
||||||
PANGO_DIRECTION_LTR, PANGO_DIRECTION_RTL, PANGO_DIRECTION_TTB_LTR,
|
PANGO_DIRECTION_LTR, PANGO_DIRECTION_RTL, PANGO_DIRECTION_TTB_LTR,
|
||||||
PANGO_DIRECTION_TTB_RTL
|
PANGO_DIRECTION_TTB_RTL
|
||||||
PPangoColor* = ptr TPangoColor
|
PPangoColor* = ptr TPangoColor
|
||||||
TPangoColor* = record
|
TPangoColor* {.final.} = object
|
||||||
red*: guint16
|
red*: guint16
|
||||||
green*: guint16
|
green*: guint16
|
||||||
blue*: guint16
|
blue*: guint16
|
||||||
|
|
@ -72,12 +72,12 @@ type
|
||||||
TPangoUnderline* = int32
|
TPangoUnderline* = int32
|
||||||
PPangoAttribute* = ptr TPangoAttribute
|
PPangoAttribute* = ptr TPangoAttribute
|
||||||
PPangoAttrClass* = ptr TPangoAttrClass
|
PPangoAttrClass* = ptr TPangoAttrClass
|
||||||
TPangoAttribute* = record
|
TPangoAttribute* {.final.} = object
|
||||||
klass*: PPangoAttrClass
|
klass*: PPangoAttrClass
|
||||||
start_index*: int
|
start_index*: int
|
||||||
end_index*: int
|
end_index*: int
|
||||||
|
|
||||||
TPangoAttrClass* = record
|
TPangoAttrClass* {.final.} = object
|
||||||
`type`*: TPangoAttrType
|
`type`*: TPangoAttrType
|
||||||
copy*: proc (attr: PPangoAttribute): PPangoAttribute{.cdecl.}
|
copy*: proc (attr: PPangoAttribute): PPangoAttribute{.cdecl.}
|
||||||
destroy*: proc (attr: PPangoAttribute){.cdecl.}
|
destroy*: proc (attr: PPangoAttribute){.cdecl.}
|
||||||
|
|
@ -85,43 +85,43 @@ type
|
||||||
cdecl.}
|
cdecl.}
|
||||||
|
|
||||||
PPangoAttrString* = ptr TPangoAttrString
|
PPangoAttrString* = ptr TPangoAttrString
|
||||||
TPangoAttrString* = record
|
TPangoAttrString* {.final.} = object
|
||||||
attr*: TPangoAttribute
|
attr*: TPangoAttribute
|
||||||
value*: cstring
|
value*: cstring
|
||||||
|
|
||||||
PPangoAttrLanguage* = ptr TPangoAttrLanguage
|
PPangoAttrLanguage* = ptr TPangoAttrLanguage
|
||||||
TPangoAttrLanguage* = record
|
TPangoAttrLanguage* {.final.} = object
|
||||||
attr*: TPangoAttribute
|
attr*: TPangoAttribute
|
||||||
value*: PPangoLanguage
|
value*: PPangoLanguage
|
||||||
|
|
||||||
PPangoAttrInt* = ptr TPangoAttrInt
|
PPangoAttrInt* = ptr TPangoAttrInt
|
||||||
TPangoAttrInt* = record
|
TPangoAttrInt* {.final.} = object
|
||||||
attr*: TPangoAttribute
|
attr*: TPangoAttribute
|
||||||
value*: int32
|
value*: int32
|
||||||
|
|
||||||
PPangoAttrFloat* = ptr TPangoAttrFloat
|
PPangoAttrFloat* = ptr TPangoAttrFloat
|
||||||
TPangoAttrFloat* = record
|
TPangoAttrFloat* {.final.} = object
|
||||||
attr*: TPangoAttribute
|
attr*: TPangoAttribute
|
||||||
value*: gdouble
|
value*: gdouble
|
||||||
|
|
||||||
PPangoAttrColor* = ptr TPangoAttrColor
|
PPangoAttrColor* = ptr TPangoAttrColor
|
||||||
TPangoAttrColor* = record
|
TPangoAttrColor* {.final.} = object
|
||||||
attr*: TPangoAttribute
|
attr*: TPangoAttribute
|
||||||
color*: TPangoColor
|
color*: TPangoColor
|
||||||
|
|
||||||
PPangoAttrShape* = ptr TPangoAttrShape
|
PPangoAttrShape* = ptr TPangoAttrShape
|
||||||
TPangoAttrShape* = record
|
TPangoAttrShape* {.final.} = object
|
||||||
attr*: TPangoAttribute
|
attr*: TPangoAttribute
|
||||||
ink_rect*: TPangoRectangle
|
ink_rect*: TPangoRectangle
|
||||||
logical_rect*: TPangoRectangle
|
logical_rect*: TPangoRectangle
|
||||||
|
|
||||||
PPangoAttrFontDesc* = ptr TPangoAttrFontDesc
|
PPangoAttrFontDesc* = ptr TPangoAttrFontDesc
|
||||||
TPangoAttrFontDesc* = record
|
TPangoAttrFontDesc* {.final.} = object
|
||||||
attr*: TPangoAttribute
|
attr*: TPangoAttribute
|
||||||
desc*: PPangoFontDescription
|
desc*: PPangoFontDescription
|
||||||
|
|
||||||
PPangoLogAttr* = ptr TPangoLogAttr
|
PPangoLogAttr* = ptr TPangoLogAttr
|
||||||
TPangoLogAttr* = record
|
TPangoLogAttr* {.final.} = object
|
||||||
flag0*: guint16
|
flag0*: guint16
|
||||||
|
|
||||||
PPangoCoverageLevel* = ptr TPangoCoverageLevel
|
PPangoCoverageLevel* = ptr TPangoCoverageLevel
|
||||||
|
|
@ -129,25 +129,25 @@ type
|
||||||
PANGO_COVERAGE_NONE, PANGO_COVERAGE_FALLBACK, PANGO_COVERAGE_APPROXIMATE,
|
PANGO_COVERAGE_NONE, PANGO_COVERAGE_FALLBACK, PANGO_COVERAGE_APPROXIMATE,
|
||||||
PANGO_COVERAGE_EXACT
|
PANGO_COVERAGE_EXACT
|
||||||
PPangoBlockInfo* = ptr TPangoBlockInfo
|
PPangoBlockInfo* = ptr TPangoBlockInfo
|
||||||
TPangoBlockInfo* = record
|
TPangoBlockInfo* {.final.} = object
|
||||||
data*: Pguchar
|
data*: Pguchar
|
||||||
level*: TPangoCoverageLevel
|
level*: TPangoCoverageLevel
|
||||||
|
|
||||||
PPangoCoverage* = ptr TPangoCoverage
|
PPangoCoverage* = ptr TPangoCoverage
|
||||||
TPangoCoverage* = record
|
TPangoCoverage* {.final.} = object
|
||||||
ref_count*: int
|
ref_count*: int
|
||||||
n_blocks*: int32
|
n_blocks*: int32
|
||||||
data_size*: int32
|
data_size*: int32
|
||||||
blocks*: PPangoBlockInfo
|
blocks*: PPangoBlockInfo
|
||||||
|
|
||||||
PPangoEngineRange* = ptr TPangoEngineRange
|
PPangoEngineRange* = ptr TPangoEngineRange
|
||||||
TPangoEngineRange* = record
|
TPangoEngineRange* {.final.} = object
|
||||||
start*: int32
|
start*: int32
|
||||||
theEnd*: int32
|
theEnd*: int32
|
||||||
langs*: cstring
|
langs*: cstring
|
||||||
|
|
||||||
PPangoEngineInfo* = ptr TPangoEngineInfo
|
PPangoEngineInfo* = ptr TPangoEngineInfo
|
||||||
TPangoEngineInfo* = record
|
TPangoEngineInfo* {.final.} = object
|
||||||
id*: cstring
|
id*: cstring
|
||||||
engine_type*: cstring
|
engine_type*: cstring
|
||||||
render_type*: cstring
|
render_type*: cstring
|
||||||
|
|
@ -155,7 +155,7 @@ type
|
||||||
n_ranges*: gint
|
n_ranges*: gint
|
||||||
|
|
||||||
PPangoEngine* = ptr TPangoEngine
|
PPangoEngine* = ptr TPangoEngine
|
||||||
TPangoEngine* = record
|
TPangoEngine* {.final.} = object
|
||||||
id*: cstring
|
id*: cstring
|
||||||
`type`*: cstring
|
`type`*: cstring
|
||||||
length*: gint
|
length*: gint
|
||||||
|
|
@ -165,7 +165,7 @@ type
|
||||||
attrs: PPangoLogAttr, attrs_len: int32){.
|
attrs: PPangoLogAttr, attrs_len: int32){.
|
||||||
cdecl.}
|
cdecl.}
|
||||||
PPangoEngineLang* = ptr TPangoEngineLang
|
PPangoEngineLang* = ptr TPangoEngineLang
|
||||||
TPangoEngineLang* = record
|
TPangoEngineLang* {.final.} = object
|
||||||
engine*: TPangoEngine
|
engine*: TPangoEngine
|
||||||
script_break*: TPangoEngineLangScriptBreak
|
script_break*: TPangoEngineLangScriptBreak
|
||||||
|
|
||||||
|
|
@ -176,7 +176,7 @@ type
|
||||||
language: PPangoLanguage): PPangoCoverage{.
|
language: PPangoLanguage): PPangoCoverage{.
|
||||||
cdecl.}
|
cdecl.}
|
||||||
PPangoEngineShape* = ptr TPangoEngineShape
|
PPangoEngineShape* = ptr TPangoEngineShape
|
||||||
TPangoEngineShape* = record
|
TPangoEngineShape* {.final.} = object
|
||||||
engine*: TPangoEngine
|
engine*: TPangoEngine
|
||||||
script_shape*: TPangoEngineShapeScript
|
script_shape*: TPangoEngineShapeScript
|
||||||
get_coverage*: TPangoEngineShapeGetCoverage
|
get_coverage*: TPangoEngineShapeGetCoverage
|
||||||
|
|
@ -194,28 +194,28 @@ type
|
||||||
PPangoGlyphUnit* = ptr TPangoGlyphUnit
|
PPangoGlyphUnit* = ptr TPangoGlyphUnit
|
||||||
TPangoGlyphUnit* = gint32
|
TPangoGlyphUnit* = gint32
|
||||||
PPangoGlyphGeometry* = ptr TPangoGlyphGeometry
|
PPangoGlyphGeometry* = ptr TPangoGlyphGeometry
|
||||||
TPangoGlyphGeometry* = record
|
TPangoGlyphGeometry* {.final.} = object
|
||||||
width*: TPangoGlyphUnit
|
width*: TPangoGlyphUnit
|
||||||
x_offset*: TPangoGlyphUnit
|
x_offset*: TPangoGlyphUnit
|
||||||
y_offset*: TPangoGlyphUnit
|
y_offset*: TPangoGlyphUnit
|
||||||
|
|
||||||
PPangoGlyphVisAttr* = ptr TPangoGlyphVisAttr
|
PPangoGlyphVisAttr* = ptr TPangoGlyphVisAttr
|
||||||
TPangoGlyphVisAttr* = record
|
TPangoGlyphVisAttr* {.final.} = object
|
||||||
flag0*: int16
|
flag0*: int16
|
||||||
|
|
||||||
PPangoGlyphInfo* = ptr TPangoGlyphInfo
|
PPangoGlyphInfo* = ptr TPangoGlyphInfo
|
||||||
TPangoGlyphInfo* = record
|
TPangoGlyphInfo* {.final.} = object
|
||||||
glyph*: TPangoGlyph
|
glyph*: TPangoGlyph
|
||||||
geometry*: TPangoGlyphGeometry
|
geometry*: TPangoGlyphGeometry
|
||||||
attr*: TPangoGlyphVisAttr
|
attr*: TPangoGlyphVisAttr
|
||||||
|
|
||||||
TPangoGlyphString* = record
|
TPangoGlyphString* {.final.} = object
|
||||||
num_glyphs*: gint
|
num_glyphs*: gint
|
||||||
glyphs*: PPangoGlyphInfo
|
glyphs*: PPangoGlyphInfo
|
||||||
log_clusters*: Pgint
|
log_clusters*: Pgint
|
||||||
space*: gint
|
space*: gint
|
||||||
|
|
||||||
TPangoAnalysis* = record
|
TPangoAnalysis* {.final.} = object
|
||||||
shape_engine*: PPangoEngineShape
|
shape_engine*: PPangoEngineShape
|
||||||
lang_engine*: PPangoEngineLang
|
lang_engine*: PPangoEngineLang
|
||||||
font*: PPangoFont
|
font*: PPangoFont
|
||||||
|
|
@ -223,7 +223,7 @@ type
|
||||||
language*: PPangoLanguage
|
language*: PPangoLanguage
|
||||||
extra_attrs*: PGSList
|
extra_attrs*: PGSList
|
||||||
|
|
||||||
TPangoItem* = record
|
TPangoItem* {.final.} = object
|
||||||
offset*: gint
|
offset*: gint
|
||||||
length*: gint
|
length*: gint
|
||||||
num_chars*: gint
|
num_chars*: gint
|
||||||
|
|
@ -236,14 +236,14 @@ type
|
||||||
TPangoWrapMode* = enum
|
TPangoWrapMode* = enum
|
||||||
PANGO_WRAP_WORD, PANGO_WRAP_CHAR
|
PANGO_WRAP_WORD, PANGO_WRAP_CHAR
|
||||||
PPangoLayoutLine* = ptr TPangoLayoutLine
|
PPangoLayoutLine* = ptr TPangoLayoutLine
|
||||||
TPangoLayoutLine* = record
|
TPangoLayoutLine* {.final.} = object
|
||||||
layout*: PPangoLayout
|
layout*: PPangoLayout
|
||||||
start_index*: gint
|
start_index*: gint
|
||||||
length*: gint
|
length*: gint
|
||||||
runs*: PGSList
|
runs*: PGSList
|
||||||
|
|
||||||
PPangoLayoutRun* = ptr TPangoLayoutRun
|
PPangoLayoutRun* = ptr TPangoLayoutRun
|
||||||
TPangoLayoutRun* = record
|
TPangoLayoutRun* {.final.} = object
|
||||||
item*: PPangoItem
|
item*: PPangoItem
|
||||||
glyphs*: PPangoGlyphString
|
glyphs*: PPangoGlyphString
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@ type
|
||||||
regMN,
|
regMN,
|
||||||
regNewline
|
regNewline
|
||||||
|
|
||||||
TRegex = record
|
TRegex = object of TObject
|
||||||
case kind: TRegexKind
|
case kind: TRegexKind
|
||||||
of regChar: c: char
|
of regChar: c: char
|
||||||
of regSet: s: ref set[char]
|
of regSet: s: ref set[char]
|
||||||
|
|
|
||||||
|
|
@ -162,7 +162,7 @@ type
|
||||||
# Data passed back in callouts
|
# Data passed back in callouts
|
||||||
# Const before type ignored
|
# Const before type ignored
|
||||||
# Pointer to character tables
|
# Pointer to character tables
|
||||||
Tpcre_extra* = record
|
Tpcre_extra* {.final.} = object
|
||||||
flags: cuint
|
flags: cuint
|
||||||
study_data: pointer
|
study_data: pointer
|
||||||
match_limit: cuint
|
match_limit: cuint
|
||||||
|
|
@ -189,7 +189,7 @@ type
|
||||||
# Offset to next item in the pattern
|
# Offset to next item in the pattern
|
||||||
# Length of next item in the pattern
|
# Length of next item in the pattern
|
||||||
# ------------------------------------------------------------------
|
# ------------------------------------------------------------------
|
||||||
TPcre_callout_block* = record
|
TPcre_callout_block* {.final.} = object
|
||||||
version: cint
|
version: cint
|
||||||
callout_number: cint
|
callout_number: cint
|
||||||
offset_vector: ptr cint
|
offset_vector: ptr cint
|
||||||
|
|
|
||||||
|
|
@ -19,10 +19,8 @@ import
|
||||||
math
|
math
|
||||||
|
|
||||||
type
|
type
|
||||||
TComplex* = record ## a complex number, consisting of a real and an
|
TComplex* = tuple[re, im: float]
|
||||||
## imaginary part
|
## a complex number, consisting of a real and an imaginary part
|
||||||
re*: float ## real part of the complex number
|
|
||||||
im*: float ## imarginary part of the complex number
|
|
||||||
|
|
||||||
proc `==` *(x, y: TComplex): bool =
|
proc `==` *(x, y: TComplex): bool =
|
||||||
## Compare two complex numbers `x` and `y` for equality.
|
## Compare two complex numbers `x` and `y` for equality.
|
||||||
|
|
|
||||||
|
|
@ -25,23 +25,24 @@ type
|
||||||
dbQuiting, # debugger wants to quit
|
dbQuiting, # debugger wants to quit
|
||||||
dbBreakpoints # debugger is only interested in breakpoints
|
dbBreakpoints # debugger is only interested in breakpoints
|
||||||
|
|
||||||
TDbgBreakpoint = record
|
TDbgBreakpoint {.final.} = object
|
||||||
low, high: int # range from low to high; if disabled
|
low, high: int # range from low to high; if disabled
|
||||||
# both low and high are set to their negative values
|
# both low and high are set to their negative values
|
||||||
# this makes the check faster and safes memory
|
# this makes the check faster and safes memory
|
||||||
filename: string
|
filename: string
|
||||||
name: string # name of breakpoint
|
name: string # name of breakpoint
|
||||||
|
|
||||||
TVarSlot {.compilerproc.} = record # variable slots used for debugger:
|
TVarSlot {.compilerproc, final.} = object # variable slots used for debugger:
|
||||||
address: pointer
|
address: pointer
|
||||||
typ: PNimType
|
typ: PNimType
|
||||||
name: cstring # for globals this is "module.name"
|
name: cstring # for globals this is "module.name"
|
||||||
|
|
||||||
PExtendedFrame = ptr TExtendedFrame
|
PExtendedFrame = ptr TExtendedFrame
|
||||||
TExtendedFrame = record # If the debugger is enabled the compiler provides
|
TExtendedFrame {.final.} = object # If the debugger is enabled the compiler
|
||||||
# an extended frame. Of course only slots that are
|
# provides an extended frame. Of course
|
||||||
# needed are allocated and not 10_000, except for
|
# only slots that are
|
||||||
# the global data description.
|
# needed are allocated and not 10_000,
|
||||||
|
# except for the global data description.
|
||||||
f: TFrame
|
f: TFrame
|
||||||
slots: array[0..10_000, TVarSlot]
|
slots: array[0..10_000, TVarSlot]
|
||||||
|
|
||||||
|
|
@ -69,7 +70,7 @@ proc findBreakpoint(name: string): int =
|
||||||
return -1
|
return -1
|
||||||
|
|
||||||
proc ListBreakPoints() =
|
proc ListBreakPoints() =
|
||||||
write(stdout, "*** emdb| Breakpoints:\n")
|
write(stdout, "*** endb| Breakpoints:\n")
|
||||||
for i in 0 .. dbgBPlen-1:
|
for i in 0 .. dbgBPlen-1:
|
||||||
write(stdout, dbgBP[i].name & ": " & $abs(dbgBP[i].low) & ".." &
|
write(stdout, dbgBP[i].name & ": " & $abs(dbgBP[i].low) & ".." &
|
||||||
$abs(dbgBP[i].high) & dbgBP[i].filename)
|
$abs(dbgBP[i].high) & dbgBP[i].filename)
|
||||||
|
|
@ -101,13 +102,13 @@ proc writeVariable(stream: TFile, slot: TVarSlot) =
|
||||||
writeln(stream, dbgRepr(slot.address, slot.typ))
|
writeln(stream, dbgRepr(slot.address, slot.typ))
|
||||||
|
|
||||||
proc ListFrame(stream: TFile, f: PExtendedFrame) =
|
proc ListFrame(stream: TFile, f: PExtendedFrame) =
|
||||||
write(stream, "*** emdb| Frame (" & $f.f.len & " slots):\n")
|
write(stream, "*** endb| Frame (" & $f.f.len & " slots):\n")
|
||||||
for i in 0 .. f.f.len-1:
|
for i in 0 .. f.f.len-1:
|
||||||
writeVariable(stream, f.slots[i])
|
writeVariable(stream, f.slots[i])
|
||||||
write(stream, "***\n")
|
write(stream, "***\n")
|
||||||
|
|
||||||
proc ListVariables(stream: TFile, f: PExtendedFrame) =
|
proc ListVariables(stream: TFile, f: PExtendedFrame) =
|
||||||
write(stream, "*** emdb| Frame (" & $f.f.len & " slots):\n")
|
write(stream, "*** endb| Frame (" & $f.f.len & " slots):\n")
|
||||||
for i in 0 .. f.f.len-1:
|
for i in 0 .. f.f.len-1:
|
||||||
writeln(stream, f.slots[i].name)
|
writeln(stream, f.slots[i].name)
|
||||||
write(stream, "***\n")
|
write(stream, "***\n")
|
||||||
|
|
@ -115,7 +116,7 @@ proc ListVariables(stream: TFile, f: PExtendedFrame) =
|
||||||
proc debugOut(msg: cstring) =
|
proc debugOut(msg: cstring) =
|
||||||
# the *** *** markers are for easy recognition of debugger
|
# the *** *** markers are for easy recognition of debugger
|
||||||
# output for external frontends.
|
# output for external frontends.
|
||||||
write(stdout, "*** emdb| ")
|
write(stdout, "*** endb| ")
|
||||||
write(stdout, msg)
|
write(stdout, msg)
|
||||||
write(stdout, "***\n")
|
write(stdout, "***\n")
|
||||||
|
|
||||||
|
|
@ -131,14 +132,14 @@ proc findVariable(frame: PExtendedFrame, varname: cstring): int =
|
||||||
|
|
||||||
proc dbgShowCurrentProc(dbgFramePointer: PFrame) =
|
proc dbgShowCurrentProc(dbgFramePointer: PFrame) =
|
||||||
if dbgFramePointer != nil:
|
if dbgFramePointer != nil:
|
||||||
write(stdout, "*** emdb| now in proc: ")
|
write(stdout, "*** endb| now in proc: ")
|
||||||
write(stdout, dbgFramePointer.procname)
|
write(stdout, dbgFramePointer.procname)
|
||||||
write(stdout, " ***\n")
|
write(stdout, " ***\n")
|
||||||
else:
|
else:
|
||||||
write(stdout, "*** emdb| (procedure name not available) ***\n")
|
write(stdout, "*** endb| (procedure name not available) ***\n")
|
||||||
|
|
||||||
proc dbgShowExecutionPoint() =
|
proc dbgShowExecutionPoint() =
|
||||||
write(stdout, "*** emdb| " & $framePtr.filename & "(" & $framePtr.line &
|
write(stdout, "*** endb| " & $framePtr.filename & "(" & $framePtr.line &
|
||||||
") " & $framePtr.procname & " ***\n")
|
") " & $framePtr.procname & " ***\n")
|
||||||
|
|
||||||
when defined(windows) or defined(dos) or defined(os2):
|
when defined(windows) or defined(dos) or defined(os2):
|
||||||
|
|
@ -219,26 +220,26 @@ h, help display this help message
|
||||||
q, quit quit the debugger and the program
|
q, quit quit the debugger and the program
|
||||||
<ENTER> repeat the previous debugger command
|
<ENTER> repeat the previous debugger command
|
||||||
EXECUTING
|
EXECUTING
|
||||||
s, stepinto single step, stepping into routine calls
|
s, step single step, stepping into routine calls
|
||||||
n, stepover single step, without stepping into routine calls
|
n, next single step, without stepping into routine calls
|
||||||
f, skipcurrent continue execution until the current routine finishes
|
f, skipcurrent continue execution until the current routine finishes
|
||||||
c, continue continue execution until the next breakpoint
|
c, continue continue execution until the next breakpoint
|
||||||
i, ignore continue execution, ignore all breakpoints
|
i, ignore continue execution, ignore all breakpoints
|
||||||
BREAKPOINTS
|
BREAKPOINTS
|
||||||
b, setbreak <name> [fromline [toline]] [file]
|
b, break <name> [fromline [toline]] [file]
|
||||||
set a new breakpoint named 'name' for line and file
|
set a new breakpoint named 'name' for line and file
|
||||||
if line or file are omitted the current one is used
|
if line or file are omitted the current one is used
|
||||||
breakpoints display the entire breakpoint list
|
breakpoints display the entire breakpoint list
|
||||||
disable <name> disable a breakpoint
|
disable <name> disable a breakpoint
|
||||||
enable <name> enable a breakpoint
|
enable <name> enable a breakpoint
|
||||||
DATA DISPLAY
|
DATA DISPLAY
|
||||||
e, eval <exp> evaluate the expression <exp>
|
e, eval <expr> evaluate the expression <expr>
|
||||||
o, out <file> <exp> evaluate <exp> and write it to <file>
|
o, out <file> <expr> evaluate <expr> and write it to <file>
|
||||||
w, where display the current execution point
|
w, where display the current execution point
|
||||||
stackframe [file] display current stack frame [and write it to file]
|
stackframe [file] display current stack frame [and write it to file]
|
||||||
u, up go up in the call stack
|
u, up go up in the call stack
|
||||||
d, down go down in the call stack
|
d, down go down in the call stack
|
||||||
callstack display the entire call stack
|
bt, backtrace display the entire call stack
|
||||||
l, locals display available local variables
|
l, locals display available local variables
|
||||||
g, globals display available global variables
|
g, globals display available global variables
|
||||||
maxdisplay <integer> set the display's recursion maximum
|
maxdisplay <integer> set the display's recursion maximum
|
||||||
|
|
@ -352,7 +353,7 @@ proc CommandPrompt() =
|
||||||
dbgDown: int = 0 # how often we did go down
|
dbgDown: int = 0 # how often we did go down
|
||||||
|
|
||||||
while again:
|
while again:
|
||||||
write(stdout, "*** emdb| >>")
|
write(stdout, "*** endb| >>")
|
||||||
var tmp = readLine(stdin)
|
var tmp = readLine(stdin)
|
||||||
if tmp.len > 0: dbgUser = tmp
|
if tmp.len > 0: dbgUser = tmp
|
||||||
# now look what we have to do:
|
# now look what we have to do:
|
||||||
|
|
@ -360,10 +361,10 @@ proc CommandPrompt() =
|
||||||
var i = scanWord(dbgUser, dbgTemp, 0)
|
var i = scanWord(dbgUser, dbgTemp, 0)
|
||||||
case dbgTemp
|
case dbgTemp
|
||||||
of "": InvalidCommand()
|
of "": InvalidCommand()
|
||||||
of "s", "stepinto":
|
of "s", "step":
|
||||||
dbgState = dbStepInto
|
dbgState = dbStepInto
|
||||||
again = false
|
again = false
|
||||||
of "n", "stepover":
|
of "n", "next":
|
||||||
dbgState = dbStepOver
|
dbgState = dbStepOver
|
||||||
dbgSkipToFrame = framePtr
|
dbgSkipToFrame = framePtr
|
||||||
again = false
|
again = false
|
||||||
|
|
@ -412,9 +413,9 @@ proc CommandPrompt() =
|
||||||
dbgShowCurrentProc(dbgFramePtr)
|
dbgShowCurrentProc(dbgFramePtr)
|
||||||
else:
|
else:
|
||||||
debugOut("[Warning] cannot go down any further ")
|
debugOut("[Warning] cannot go down any further ")
|
||||||
of "callstack":
|
of "bt", "backtrace":
|
||||||
WriteStackTrace()
|
WriteStackTrace()
|
||||||
of "b", "setbreak":
|
of "b", "break":
|
||||||
setBreakPoint(dbgUser, i)
|
setBreakPoint(dbgUser, i)
|
||||||
of "breakpoints":
|
of "breakpoints":
|
||||||
ListBreakPoints()
|
ListBreakPoints()
|
||||||
|
|
@ -443,7 +444,7 @@ proc endbStep() =
|
||||||
proc checkForBreakpoint() =
|
proc checkForBreakpoint() =
|
||||||
var i = dbgBreakpointReached(framePtr.line)
|
var i = dbgBreakpointReached(framePtr.line)
|
||||||
if i >= 0:
|
if i >= 0:
|
||||||
write(stdout, "*** emdb| reached ")
|
write(stdout, "*** endb| reached ")
|
||||||
write(stdout, dbgBP[i].name)
|
write(stdout, dbgBP[i].name)
|
||||||
write(stdout, " in ")
|
write(stdout, " in ")
|
||||||
write(stdout, framePtr.filename)
|
write(stdout, framePtr.filename)
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,8 @@
|
||||||
#define ABORT_ON_ASSERT_FAILURE 0
|
#define ABORT_ON_ASSERT_FAILURE 0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#define ABORT do { printf("abort was called\n"); abort(); } while (0)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
This is a version (aka dlmalloc) of malloc/free/realloc written by
|
This is a version (aka dlmalloc) of malloc/free/realloc written by
|
||||||
Doug Lea and released to the public domain, as explained at
|
Doug Lea and released to the public domain, as explained at
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
# Nimrod's Runtime Library
|
# Nimrod's Runtime Library
|
||||||
# (c) Copyright 2006 Andreas Rumpf
|
# (c) Copyright 2008 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.
|
||||||
|
|
@ -35,35 +35,34 @@ proc chckNil(p: pointer) {.inline, compilerproc.}
|
||||||
|
|
||||||
type
|
type
|
||||||
PSafePoint = ptr TSafePoint
|
PSafePoint = ptr TSafePoint
|
||||||
TSafePoint {.compilerproc.} = record
|
TSafePoint {.compilerproc, final.} = object
|
||||||
prev: PSafePoint # points to next safe point ON THE STACK
|
prev: PSafePoint # points to next safe point ON THE STACK
|
||||||
exc: ref E_Base
|
exc: ref E_Base
|
||||||
status: int
|
status: int
|
||||||
context: C_JmpBuf
|
context: C_JmpBuf
|
||||||
|
|
||||||
var
|
var
|
||||||
excHandler {.compilerproc, volatile.}: PSafePoint = nil
|
excHandler {.compilerproc.}: PSafePoint = nil
|
||||||
# list of exception handlers
|
# list of exception handlers
|
||||||
# a global variable for the root of all try blocks
|
# a global variable for the root of all try blocks
|
||||||
|
|
||||||
proc reraiseException() =
|
proc reraiseException() =
|
||||||
if excHandler != nil:
|
if excHandler == nil:
|
||||||
raise newException(ENoExceptionToReraise, "no exception to reraise")
|
raise newException(ENoExceptionToReraise, "no exception to reraise")
|
||||||
else:
|
else:
|
||||||
c_longjmp(excHandler.context, 1)
|
c_longjmp(excHandler.context, 1)
|
||||||
|
|
||||||
type
|
type
|
||||||
PFrame = ptr TFrame
|
PFrame = ptr TFrame
|
||||||
TFrame {.importc, nodecl.} = record
|
TFrame {.importc, nodecl, final.} = object
|
||||||
prev: PFrame
|
prev: PFrame
|
||||||
procname: CString
|
procname: CString
|
||||||
line: int # current line number
|
line: int # current line number
|
||||||
filename: CString
|
filename: CString
|
||||||
len: int # length of slots (when not debugging always zero)
|
len: int # length of slots (when not debugging always zero)
|
||||||
|
|
||||||
TTempFrame = record # used for recursion elimination in WriteStackTrace
|
TTempFrame = tuple[ # used for recursion elimination in WriteStackTrace
|
||||||
procname: CString
|
procname: CString, line: int]
|
||||||
line: int
|
|
||||||
|
|
||||||
var
|
var
|
||||||
buf: string # cannot be allocated on the stack!
|
buf: string # cannot be allocated on the stack!
|
||||||
|
|
@ -71,7 +70,7 @@ var
|
||||||
# assert, as it raises an exception and
|
# assert, as it raises an exception and
|
||||||
# exception handler needs the buffer too
|
# exception handler needs the buffer too
|
||||||
|
|
||||||
framePtr {.exportc, volatile.}: PFrame
|
framePtr {.exportc.}: PFrame
|
||||||
|
|
||||||
tempFrames: array [0..255, TTempFrame] # cannot be allocated
|
tempFrames: array [0..255, TTempFrame] # cannot be allocated
|
||||||
# on the stack!
|
# on the stack!
|
||||||
|
|
@ -82,8 +81,7 @@ proc auxWriteStackTrace(f: PFrame, s: var string) =
|
||||||
i = 0
|
i = 0
|
||||||
total = 0
|
total = 0
|
||||||
while it != nil and i <= high(tempFrames):
|
while it != nil and i <= high(tempFrames):
|
||||||
tempFrames[i].procname = it.procname
|
tempFrames[i] = (it.procname, it.line)
|
||||||
tempFrames[i].line = it.line
|
|
||||||
inc(i)
|
inc(i)
|
||||||
inc(total)
|
inc(total)
|
||||||
it = it.prev
|
it = it.prev
|
||||||
|
|
@ -110,10 +108,10 @@ proc rawWriteStackTrace(s: var string) =
|
||||||
auxWriteStackTrace(framePtr, s)
|
auxWriteStackTrace(framePtr, s)
|
||||||
|
|
||||||
proc quitOrDebug() {.inline.} =
|
proc quitOrDebug() {.inline.} =
|
||||||
when not defined(emdb):
|
when not defined(endb):
|
||||||
quit(1)
|
quit(1)
|
||||||
else:
|
else:
|
||||||
emdbStep() # call the debugger
|
endbStep() # call the debugger
|
||||||
|
|
||||||
proc raiseException(e: ref E_Base, ename: CString) =
|
proc raiseException(e: ref E_Base, ename: CString) =
|
||||||
GC_disable() # a bad thing is an error in the GC while raising an exception
|
GC_disable() # a bad thing is an error in the GC while raising an exception
|
||||||
|
|
@ -122,7 +120,7 @@ proc raiseException(e: ref E_Base, ename: CString) =
|
||||||
excHandler.exc = e
|
excHandler.exc = e
|
||||||
c_longjmp(excHandler.context, 1)
|
c_longjmp(excHandler.context, 1)
|
||||||
else:
|
else:
|
||||||
if cast[pointer](buf) != nil:
|
if not isNil(buf):
|
||||||
setLen(buf, 0)
|
setLen(buf, 0)
|
||||||
rawWriteStackTrace(buf)
|
rawWriteStackTrace(buf)
|
||||||
if e.msg != nil and e.msg[0] != '\0':
|
if e.msg != nil and e.msg[0] != '\0':
|
||||||
|
|
@ -135,9 +133,7 @@ proc raiseException(e: ref E_Base, ename: CString) =
|
||||||
add(buf, "]\n")
|
add(buf, "]\n")
|
||||||
writeToStdErr(buf)
|
writeToStdErr(buf)
|
||||||
else:
|
else:
|
||||||
writeToStdErr("*** FATAL ERROR *** ")
|
|
||||||
writeToStdErr(ename)
|
writeToStdErr(ename)
|
||||||
writeToStdErr("\n")
|
|
||||||
quitOrDebug()
|
quitOrDebug()
|
||||||
GC_enable()
|
GC_enable()
|
||||||
|
|
||||||
|
|
@ -147,7 +143,8 @@ var
|
||||||
proc internalAssert(file: cstring, line: int, cond: bool) {.compilerproc.} =
|
proc internalAssert(file: cstring, line: int, cond: bool) {.compilerproc.} =
|
||||||
if not cond:
|
if not cond:
|
||||||
GC_disable() # BUGFIX: `$` allocates a new string object!
|
GC_disable() # BUGFIX: `$` allocates a new string object!
|
||||||
if cast[pointer](assertBuf) != nil: # BUGFIX: when debugging the GC, assertBuf may be nil
|
if not isNil(assertBuf):
|
||||||
|
# BUGFIX: when debugging the GC, assertBuf may be nil
|
||||||
setLen(assertBuf, 0)
|
setLen(assertBuf, 0)
|
||||||
add(assertBuf, "[Assertion failure] file: ")
|
add(assertBuf, "[Assertion failure] file: ")
|
||||||
add(assertBuf, file)
|
add(assertBuf, file)
|
||||||
|
|
@ -164,6 +161,11 @@ proc WriteStackTrace() =
|
||||||
rawWriteStackTrace(s)
|
rawWriteStackTrace(s)
|
||||||
writeToStdErr(s)
|
writeToStdErr(s)
|
||||||
|
|
||||||
|
#proc stackTraceWrapper {.noconv.} =
|
||||||
|
# writeStackTrace()
|
||||||
|
|
||||||
|
#addQuitProc(stackTraceWrapper)
|
||||||
|
|
||||||
var
|
var
|
||||||
dbgAborting: bool # whether the debugger wants to abort
|
dbgAborting: bool # whether the debugger wants to abort
|
||||||
|
|
||||||
|
|
@ -171,6 +173,7 @@ proc signalHandler(sig: cint) {.exportc: "signalHandler", noconv.} =
|
||||||
# print stack trace and quit
|
# print stack trace and quit
|
||||||
var
|
var
|
||||||
s = int(sig)
|
s = int(sig)
|
||||||
|
GC_disable()
|
||||||
setLen(buf, 0)
|
setLen(buf, 0)
|
||||||
rawWriteStackTrace(buf)
|
rawWriteStackTrace(buf)
|
||||||
|
|
||||||
|
|
@ -185,6 +188,7 @@ proc signalHandler(sig: cint) {.exportc: "signalHandler", noconv.} =
|
||||||
else: add(buf, "unknown signal\n")
|
else: add(buf, "unknown signal\n")
|
||||||
writeToStdErr(buf)
|
writeToStdErr(buf)
|
||||||
dbgAborting = True # play safe here...
|
dbgAborting = True # play safe here...
|
||||||
|
GC_enable()
|
||||||
quit(1) # always quit when SIGABRT
|
quit(1) # always quit when SIGABRT
|
||||||
|
|
||||||
proc registerSignalHandler() =
|
proc registerSignalHandler() =
|
||||||
|
|
@ -204,12 +208,15 @@ assertBuf = newString(2048)
|
||||||
setLen(buf, 0)
|
setLen(buf, 0)
|
||||||
setLen(assertBuf, 0)
|
setLen(assertBuf, 0)
|
||||||
|
|
||||||
proc raiseRangeError() {.compilerproc, noreturn.} =
|
proc raiseRangeError(val: biggestInt) {.compilerproc, noreturn.} =
|
||||||
raise newException(EOutOfRange, "value out of range")
|
raise newException(EOutOfRange, "value " & $val & " out of range")
|
||||||
|
|
||||||
proc raiseIndexError() {.compilerproc, noreturn.} =
|
proc raiseIndexError() {.compilerproc, noreturn.} =
|
||||||
raise newException(EInvalidIndex, "index out of bounds")
|
raise newException(EInvalidIndex, "index out of bounds")
|
||||||
|
|
||||||
|
proc raiseFieldError(f: string) {.compilerproc, noreturn.} =
|
||||||
|
raise newException(EInvalidField, f & " is not accessible")
|
||||||
|
|
||||||
proc chckIndx(i, a, b: int): int =
|
proc chckIndx(i, a, b: int): int =
|
||||||
if i >= a and i <= b:
|
if i >= a and i <= b:
|
||||||
return i
|
return i
|
||||||
|
|
@ -220,19 +227,19 @@ proc chckRange(i, a, b: int): int =
|
||||||
if i >= a and i <= b:
|
if i >= a and i <= b:
|
||||||
return i
|
return i
|
||||||
else:
|
else:
|
||||||
raiseRangeError()
|
raiseRangeError(i)
|
||||||
|
|
||||||
proc chckRange64(i, a, b: int64): int64 {.compilerproc.} =
|
proc chckRange64(i, a, b: int64): int64 {.compilerproc.} =
|
||||||
if i >= a and i <= b:
|
if i >= a and i <= b:
|
||||||
return i
|
return i
|
||||||
else:
|
else:
|
||||||
raiseRangeError()
|
raiseRangeError(i)
|
||||||
|
|
||||||
proc chckRangeF(x, a, b: float): float =
|
proc chckRangeF(x, a, b: float): float =
|
||||||
if x >= a and x <= b:
|
if x >= a and x <= b:
|
||||||
return x
|
return x
|
||||||
else:
|
else:
|
||||||
raiseRangeError()
|
raise newException(EOutOfRange, "value " & $x & " out of range")
|
||||||
|
|
||||||
proc chckNil(p: pointer) =
|
proc chckNil(p: pointer) =
|
||||||
if p == nil: c_raise(SIGSEGV)
|
if p == nil: c_raise(SIGSEGV)
|
||||||
|
|
|
||||||
570
lib/gc.nim
570
lib/gc.nim
|
|
@ -1,7 +1,7 @@
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
# Nimrod's Runtime Library
|
# Nimrod's Runtime Library
|
||||||
# (c) Copyright 2006 Andreas Rumpf
|
# (c) Copyright 2008 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.
|
||||||
|
|
@ -13,33 +13,39 @@
|
||||||
# For a description of the algorithms used here see:
|
# For a description of the algorithms used here see:
|
||||||
# intern.html
|
# intern.html
|
||||||
|
|
||||||
#{.define: debugGC.} # we wish to debug the GC...
|
{.define: debugGC.} # we wish to debug the GC...
|
||||||
|
|
||||||
#when defined(debugGC):
|
#when defined(debugGC):
|
||||||
# {.define: logGC.} # define if the GC should log some of its activities
|
# {.define: logGC.} # define if the GC should log some of its activities
|
||||||
|
|
||||||
{.define: cycleGC.}
|
{.define: cycleGC.}
|
||||||
|
|
||||||
|
const
|
||||||
|
traceGC = false # extensive debugging
|
||||||
|
reallyDealloc = true # for debugging purposes this can be set to false
|
||||||
|
|
||||||
# Guess the page size of the system; if it is the
|
# Guess the page size of the system; if it is the
|
||||||
# wrong value, performance may be worse (this is not
|
# wrong value, performance may be worse (this is not
|
||||||
# for sure though), but GC still works; must be a power of two!
|
# for sure though), but GC still works; must be a power of two!
|
||||||
const
|
const
|
||||||
PageSize = 1024 * sizeof(int)
|
PageShift = if sizeof(pointer) == 4: 12 else: 13
|
||||||
RC_Increase = 7 * PageSize # is an additive increase
|
PageSize = 1 shl PageShift # on 32 bit systems 4096
|
||||||
CycleIncrease = 2 # is a multiplicative increase
|
CycleIncrease = 2 # is a multiplicative increase
|
||||||
|
|
||||||
|
InitialCycleThreshold = 8*1024*1024 # X MB because cycle checking is slow
|
||||||
|
ZctThreshold = 512 # we collect garbage if the ZCT's size
|
||||||
|
# reaches this threshold
|
||||||
|
# this needs benchmarking...
|
||||||
|
|
||||||
when defined(debugGC):
|
when defined(debugGC):
|
||||||
const InitialThreshold = 64*1024
|
const stressGC = False
|
||||||
const stressGC = True # GC is debugged; no need to stress it
|
|
||||||
else:
|
else:
|
||||||
const stressGC = False
|
const stressGC = False
|
||||||
const InitialThreshold = RC_Increase
|
|
||||||
# this may need benchmarking...
|
|
||||||
|
|
||||||
# things the System module thinks should be available:
|
# things the System module thinks should be available:
|
||||||
when defined(useDL) or defined(nativeDL):
|
when defined(useDL) or defined(nativeDL):
|
||||||
type
|
type
|
||||||
TMallocInfo {.importc: "struct mallinfo", nodecl.} = record
|
TMallocInfo {.importc: "struct mallinfo", nodecl, final.} = object
|
||||||
arena: cint # non-mmapped space allocated from system
|
arena: cint # non-mmapped space allocated from system
|
||||||
ordblks: cint # number of free chunks
|
ordblks: cint # number of free chunks
|
||||||
smblks: cint # number of fastbin blocks
|
smblks: cint # number of fastbin blocks
|
||||||
|
|
@ -68,8 +74,7 @@ else: # not available:
|
||||||
proc getTotalMem(): int = return -1
|
proc getTotalMem(): int = return -1
|
||||||
|
|
||||||
var
|
var
|
||||||
rcThreshold: int = InitialThreshold
|
cycleThreshold: int = InitialCycleThreshold
|
||||||
cycleThreshold: int = InitialThreshold
|
|
||||||
|
|
||||||
memUsed: int = 0 # we have to keep track how much we have allocated
|
memUsed: int = 0 # we have to keep track how much we have allocated
|
||||||
|
|
||||||
|
|
@ -113,9 +118,10 @@ type
|
||||||
waNone, waRelease, waZctDecRef, waCycleDecRef, waCycleIncRef, waDebugIncRef
|
waNone, waRelease, waZctDecRef, waCycleDecRef, waCycleIncRef, waDebugIncRef
|
||||||
|
|
||||||
TCollectorData = int
|
TCollectorData = int
|
||||||
TCell = record
|
TCell {.final.} = object
|
||||||
refcount: TCollectorData # the refcount and bit flags
|
refcount: TCollectorData # the refcount and bit flags
|
||||||
typ: PNimType
|
typ: PNimType
|
||||||
|
when stressGC:
|
||||||
stackcount: int # stack counter for debugging
|
stackcount: int # stack counter for debugging
|
||||||
drefc: int # real reference counter for debugging
|
drefc: int # real reference counter for debugging
|
||||||
|
|
||||||
|
|
@ -145,6 +151,7 @@ proc extGetCellType(c: pointer): PNimType {.compilerproc.} =
|
||||||
|
|
||||||
proc internRefcount(p: pointer): int {.exportc: "getRefcount".} =
|
proc internRefcount(p: pointer): int {.exportc: "getRefcount".} =
|
||||||
result = int(usrToCell(p).refcount)
|
result = int(usrToCell(p).refcount)
|
||||||
|
if result < 0: result = 0
|
||||||
|
|
||||||
proc gcAlloc(size: int): pointer =
|
proc gcAlloc(size: int): pointer =
|
||||||
result = alloc0(size)
|
result = alloc0(size)
|
||||||
|
|
@ -162,7 +169,7 @@ proc GC_setStrategy(strategy: TGC_Strategy) =
|
||||||
of gcOptimizeTime: nil
|
of gcOptimizeTime: nil
|
||||||
|
|
||||||
proc GC_enableMarkAndSweep() =
|
proc GC_enableMarkAndSweep() =
|
||||||
cycleThreshold = InitialThreshold
|
cycleThreshold = InitialCycleThreshold
|
||||||
|
|
||||||
proc GC_disableMarkAndSweep() =
|
proc GC_disableMarkAndSweep() =
|
||||||
cycleThreshold = high(cycleThreshold)-1
|
cycleThreshold = high(cycleThreshold)-1
|
||||||
|
|
@ -174,7 +181,7 @@ proc nextTry(h, maxHash: int): int {.inline.} =
|
||||||
# generates each int in range(maxHash) exactly once (see any text on
|
# generates each int in range(maxHash) exactly once (see any text on
|
||||||
# random-number generation for proof).
|
# random-number generation for proof).
|
||||||
|
|
||||||
# ------------------ Zero count table (ZCT) and any table (AT) -------------
|
# ------------------ Any table (AT) -------------
|
||||||
|
|
||||||
# these values are for DL-malloc known for sure (and other allocators
|
# these values are for DL-malloc known for sure (and other allocators
|
||||||
# can only be worse):
|
# can only be worse):
|
||||||
|
|
@ -200,8 +207,7 @@ when BitsPerPage mod BitsPerUnit != 0:
|
||||||
|
|
||||||
# ------------------- cell set handling ------------------------------
|
# ------------------- cell set handling ------------------------------
|
||||||
# A cellset consists of a hash table of page descriptors. A page
|
# A cellset consists of a hash table of page descriptors. A page
|
||||||
# descriptor has a bit for
|
# descriptor has a bit for every Memalignment'th byte in the page.
|
||||||
# every Memalignment'th byte in the page.
|
|
||||||
# However, only bits corresponding to addresses that start memory blocks
|
# However, only bits corresponding to addresses that start memory blocks
|
||||||
# are set.
|
# are set.
|
||||||
# Page descriptors are also linked to a list; the list
|
# Page descriptors are also linked to a list; the list
|
||||||
|
|
@ -217,17 +223,59 @@ type
|
||||||
|
|
||||||
TBitIndex = range[0..UnitsPerPage-1]
|
TBitIndex = range[0..UnitsPerPage-1]
|
||||||
|
|
||||||
TPageDesc = record
|
TPageDesc {.final.} = object
|
||||||
next: PPageDesc # all nodes are connected with this pointer
|
next: PPageDesc # all nodes are connected with this pointer
|
||||||
key: TAddress # start address at bit 0
|
key: TAddress # start address at bit 0
|
||||||
bits: array[TBitIndex, int] # a bit vector
|
bits: array[TBitIndex, int] # a bit vector
|
||||||
|
|
||||||
PPageDescArray = ptr array[0..1000_000, PPageDesc]
|
PPageDescArray = ptr array[0..1000_000, PPageDesc]
|
||||||
TCellSet = record
|
TCellSet {.final.} = object
|
||||||
counter, max: int
|
counter, max: int
|
||||||
head: PPageDesc
|
head: PPageDesc
|
||||||
data: PPageDescArray
|
data: PPageDescArray
|
||||||
|
|
||||||
|
PCellArray = ptr array[0..100_000_000, PCell]
|
||||||
|
TCellSeq {.final.} = object
|
||||||
|
len, cap: int
|
||||||
|
d: PCellArray
|
||||||
|
|
||||||
|
TSlowSet {.final.} = object # used for debugging purposes only
|
||||||
|
L: int # current length
|
||||||
|
cap: int # capacity
|
||||||
|
d: PCellArray
|
||||||
|
|
||||||
|
TGcHeap {.final.} = object # this contains the zero count and
|
||||||
|
# non-zero count table
|
||||||
|
mask: TAddress # mask for fast pointer detection
|
||||||
|
zct: TCellSeq # the zero count table
|
||||||
|
at: TCellSet # a table that contains all references
|
||||||
|
newAT: TCellSet
|
||||||
|
stackCells: TCellSeq # cells that need to be decremented because they
|
||||||
|
# are in the hardware stack; a cell may occur
|
||||||
|
# several times in this data structure
|
||||||
|
|
||||||
|
var
|
||||||
|
stackBottom: pointer
|
||||||
|
gch: TGcHeap
|
||||||
|
|
||||||
|
proc add(s: var TCellSeq, c: PCell) {.inline.} =
|
||||||
|
if s.len >= s.cap:
|
||||||
|
s.cap = s.cap * 3 div 2
|
||||||
|
s.d = cast[PCellArray](realloc(s.d, s.cap * sizeof(PCell)))
|
||||||
|
if s.d == nil: raiseOutOfMem()
|
||||||
|
s.d[s.len] = c
|
||||||
|
inc(s.len)
|
||||||
|
|
||||||
|
proc inOperator(s: TCellSeq, c: PCell): bool {.inline.} =
|
||||||
|
for i in 0 .. s.len-1:
|
||||||
|
if s.d[i] == c: return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
proc init(s: var TCellSeq, cap: int = 1024) =
|
||||||
|
s.len = 0
|
||||||
|
s.cap = cap
|
||||||
|
s.d = cast[PCellArray](gcAlloc(cap * sizeof(PCell)))
|
||||||
|
|
||||||
const
|
const
|
||||||
InitCellSetSize = 1024 # must be a power of two!
|
InitCellSetSize = 1024 # must be a power of two!
|
||||||
|
|
||||||
|
|
@ -284,7 +332,8 @@ proc CellSetPut(t: var TCellSet, key: TAddress): PPageDesc =
|
||||||
if x.key == key: return x
|
if x.key == key: return x
|
||||||
h = nextTry(h, t.max)
|
h = nextTry(h, t.max)
|
||||||
|
|
||||||
if (t.max+1) * 2 < t.counter * 3: CellSetEnlarge(t)
|
if ((t.max+1)*2 < t.counter*3) or ((t.max+1)-t.counter < 4):
|
||||||
|
CellSetEnlarge(t)
|
||||||
inc(t.counter)
|
inc(t.counter)
|
||||||
h = cast[int](key) and t.max
|
h = cast[int](key) and t.max
|
||||||
while t.data[h] != nil: h = nextTry(h, t.max)
|
while t.data[h] != nil: h = nextTry(h, t.max)
|
||||||
|
|
@ -303,7 +352,7 @@ proc in_Operator(s: TCellSet, cell: PCell): bool =
|
||||||
u: TAddress
|
u: TAddress
|
||||||
t: PPageDesc
|
t: PPageDesc
|
||||||
u = cast[TAddress](cell)
|
u = cast[TAddress](cell)
|
||||||
t = CellSetGet(s, u /% PageSize)
|
t = CellSetGet(s, u shr PageShift)
|
||||||
if t != nil:
|
if t != nil:
|
||||||
u = (u %% PageSize) /% MemAlignment
|
u = (u %% PageSize) /% MemAlignment
|
||||||
result = (t.bits[u /% BitsPerUnit] and (1 shl (u %% BitsPerUnit))) != 0
|
result = (t.bits[u /% BitsPerUnit] and (1 shl (u %% BitsPerUnit))) != 0
|
||||||
|
|
@ -315,7 +364,7 @@ proc incl(s: var TCellSet, cell: PCell) =
|
||||||
u: TAddress
|
u: TAddress
|
||||||
t: PPageDesc
|
t: PPageDesc
|
||||||
u = cast[TAddress](cell)
|
u = cast[TAddress](cell)
|
||||||
t = CellSetPut(s, u /% PageSize)
|
t = CellSetPut(s, u shr PageShift)
|
||||||
u = (u %% PageSize) /% MemAlignment
|
u = (u %% PageSize) /% MemAlignment
|
||||||
t.bits[u /% BitsPerUnit] = t.bits[u /% BitsPerUnit] or
|
t.bits[u /% BitsPerUnit] = t.bits[u /% BitsPerUnit] or
|
||||||
(1 shl (u %% BitsPerUnit))
|
(1 shl (u %% BitsPerUnit))
|
||||||
|
|
@ -325,7 +374,7 @@ proc excl(s: var TCellSet, cell: PCell) =
|
||||||
u: TAddress
|
u: TAddress
|
||||||
t: PPageDesc
|
t: PPageDesc
|
||||||
u = cast[TAddress](cell)
|
u = cast[TAddress](cell)
|
||||||
t = CellSetGet(s, u /% PageSize)
|
t = CellSetGet(s, u shr PageShift)
|
||||||
if t != nil:
|
if t != nil:
|
||||||
u = (u %% PageSize) /% MemAlignment
|
u = (u %% PageSize) /% MemAlignment
|
||||||
t.bits[u /% BitsPerUnit] = (t.bits[u /% BitsPerUnit] and
|
t.bits[u /% BitsPerUnit] = (t.bits[u /% BitsPerUnit] and
|
||||||
|
|
@ -342,7 +391,7 @@ iterator elements(t: TCellSet): PCell {.inline.} =
|
||||||
var j = 0
|
var j = 0
|
||||||
while w != 0: # test all remaining bits for zero
|
while w != 0: # test all remaining bits for zero
|
||||||
if (w and 1) != 0: # the bit is set!
|
if (w and 1) != 0: # the bit is set!
|
||||||
yield cast[PCell]((r.key *% PageSize) +%
|
yield cast[PCell]((r.key shl PageShift) or # +%
|
||||||
(i*%BitsPerUnit+%j) *% MemAlignment)
|
(i*%BitsPerUnit+%j) *% MemAlignment)
|
||||||
inc(j)
|
inc(j)
|
||||||
w = w shr 1
|
w = w shr 1
|
||||||
|
|
@ -354,68 +403,121 @@ iterator elements(t: TCellSet): PCell {.inline.} =
|
||||||
proc testPageDescs() =
|
proc testPageDescs() =
|
||||||
var root: TCellSet
|
var root: TCellSet
|
||||||
CellSetInit(root)
|
CellSetInit(root)
|
||||||
var u = 10_000
|
#var u = 10_000
|
||||||
while u <= 20_000:
|
#while u <= 20_000:
|
||||||
incl(root, cast[PCell](u))
|
# incl(root, cast[PCell](u))
|
||||||
inc(u, 8)
|
# inc(u, 8)
|
||||||
|
|
||||||
|
incl(root, cast[PCell](0x81cdfb8))
|
||||||
for cell in elements(root):
|
for cell in elements(root):
|
||||||
c_fprintf(c_stdout, "%ld\n", cast[int](cell))
|
c_fprintf(c_stdout, "%p\n", cast[int](cell))
|
||||||
|
|
||||||
#testPageDescs()
|
#testPageDescs()
|
||||||
|
|
||||||
when defined(debugGC):
|
when defined(debugGC):
|
||||||
proc writeCell(msg: CString, c: PCell) =
|
proc writeCell(msg: CString, c: PCell) =
|
||||||
c_fprintf(c_stdout, "%s: %p\n", msg, c)
|
if c.typ != nil:
|
||||||
|
if c.typ.kind == tyString:
|
||||||
|
c_fprintf(c_stdout, "%s\n", cast[TAddress](cellToUsr(c)) + sizeof(int)*2)
|
||||||
|
c_fprintf(c_stdout, "%s: %p %d\n", msg, c, c.typ.kind)
|
||||||
|
else: c_fprintf(c_stdout, "%s: %p (nil type)\n", msg, c)
|
||||||
proc writePtr(msg: CString, p: Pointer) =
|
proc writePtr(msg: CString, p: Pointer) =
|
||||||
c_fprintf(c_stdout, "%s: %p\n", msg, p)
|
c_fprintf(c_stdout, "%s: %p\n", msg, p)
|
||||||
|
|
||||||
# -------------------------------------------------------------------------
|
|
||||||
|
|
||||||
|
when traceGC:
|
||||||
|
# traceGC is a special switch to enable extensive debugging
|
||||||
type
|
type
|
||||||
PStackCells = ptr array[0..1000_0000, PCell]
|
TCellState = enum
|
||||||
TCountTables = record # this contains the zero count and
|
csAllocated, csZctFreed, csCycFreed
|
||||||
# non-zero count table
|
|
||||||
mask: TAddress # mask for fast pointer detection
|
|
||||||
zct: TCellSet # the zero count table
|
|
||||||
at: TCellSet # a table that contains all references
|
|
||||||
newAT: TCellSet
|
|
||||||
newZCT: TCellSet
|
|
||||||
stackCells: PStackCells # cells that need to be decremented because they
|
|
||||||
# are in the hardware stack; a cell may occur
|
|
||||||
# several times in this data structure
|
|
||||||
stackLen, stackMax: int # for managing the stack cells
|
|
||||||
|
|
||||||
proc addStackCell(ct: var TCountTables, cell: PCell) =
|
proc cellSetInit(s: var TSlowSet) =
|
||||||
if ct.stackLen >= ct.stackMax:
|
s.L = 0
|
||||||
ct.stackMax = ct.stackMax * 3 div 2
|
s.cap = 4096
|
||||||
ct.stackCells = cast[PStackCells](realloc(ct.stackCells, ct.stackMax *
|
s.d = cast[PCellArray](gcAlloc(s.cap * sizeof(PCell)))
|
||||||
sizeof(PCell)))
|
|
||||||
if ct.stackCells == nil: raiseOutOfMem()
|
proc cellSetDeinit(s: var TSlowSet) =
|
||||||
ct.stackCells[ct.stackLen] = cell
|
s.L = 0
|
||||||
inc(ct.stackLen)
|
s.cap = 0
|
||||||
|
dealloc(s.d)
|
||||||
|
|
||||||
|
proc incl(s: var TSlowSet, c: PCell) =
|
||||||
|
if s.L >= s.cap:
|
||||||
|
s.cap = s.cap * 3 div 2
|
||||||
|
s.d = cast[PCellArray](realloc(s.d, s.cap * sizeof(PCell)))
|
||||||
|
if s.d == nil: raiseOutOfMem()
|
||||||
|
s.d[s.L] = c
|
||||||
|
inc(s.L)
|
||||||
|
|
||||||
|
proc excl(s: var TSlowSet, c: PCell) =
|
||||||
|
var i = 0
|
||||||
|
while i < s.L:
|
||||||
|
if s.d[i] == c:
|
||||||
|
s.d[i] = s.d[s.L-1]
|
||||||
|
dec(s.L)
|
||||||
|
break
|
||||||
|
inc(i)
|
||||||
|
|
||||||
|
proc inOperator(s: TSlowSet, c: PCell): bool =
|
||||||
|
var i = 0
|
||||||
|
while i < s.L:
|
||||||
|
if s.d[i] == c: return true
|
||||||
|
inc(i)
|
||||||
|
|
||||||
|
iterator elements(s: TSlowSet): PCell =
|
||||||
|
var i = 0
|
||||||
|
while i < s.L:
|
||||||
|
yield s.d[i]
|
||||||
|
inc(i)
|
||||||
|
|
||||||
var
|
var
|
||||||
stackBottom: pointer
|
states: array[TCellState, TSlowSet] # TCellSet]
|
||||||
ct: TCountTables
|
|
||||||
|
|
||||||
proc GC_invariant(): bool =
|
proc traceCell(c: PCell, state: TCellState) =
|
||||||
result = True
|
case state
|
||||||
when stressGC:
|
of csAllocated:
|
||||||
if recGcLock == 0:
|
if c in states[csAllocated]:
|
||||||
GC_disable()
|
writeCell("attempt to alloc a already allocated cell", c)
|
||||||
for cell in elements(ct.at):
|
|
||||||
var t = cell.typ # getCellType(cell)
|
|
||||||
if t == nil or t.kind notin {tySequence, tyString, tyRef}:
|
|
||||||
writeCell("corrupt cell?", cell)
|
|
||||||
result = false
|
|
||||||
GC_enable()
|
|
||||||
|
|
||||||
when stressGC:
|
|
||||||
proc GCdebugHook() =
|
|
||||||
if not GC_invariant():
|
|
||||||
assert(false)
|
assert(false)
|
||||||
|
excl(states[csCycFreed], c)
|
||||||
|
excl(states[csZctFreed], c)
|
||||||
|
of csZctFreed:
|
||||||
|
if c notin states[csAllocated]:
|
||||||
|
writeCell("attempt to free a not allocated cell", c)
|
||||||
|
assert(false)
|
||||||
|
if c in states[csZctFreed]:
|
||||||
|
writeCell("attempt to free zct cell twice", c)
|
||||||
|
assert(false)
|
||||||
|
if c in states[csCycFreed]:
|
||||||
|
writeCell("attempt to free with zct, but already freed with cyc", c)
|
||||||
|
assert(false)
|
||||||
|
excl(states[csAllocated], c)
|
||||||
|
of csCycFreed:
|
||||||
|
if c notin states[csAllocated]:
|
||||||
|
writeCell("attempt to free a not allocated cell", c)
|
||||||
|
assert(false)
|
||||||
|
if c in states[csCycFreed]:
|
||||||
|
writeCell("attempt to free cyc cell twice", c)
|
||||||
|
assert(false)
|
||||||
|
if c in states[csZctFreed]:
|
||||||
|
writeCell("attempt to free with cyc, but already freed with zct", c)
|
||||||
|
assert(false)
|
||||||
|
excl(states[csAllocated], c)
|
||||||
|
incl(states[state], c)
|
||||||
|
|
||||||
dbgLineHook = GCdebugHook
|
template gcTrace(cell, state: expr): stmt =
|
||||||
|
when traceGC: traceCell(cell, state)
|
||||||
|
|
||||||
|
# -------------------------------------------------------------------------
|
||||||
|
|
||||||
|
# forward declarations:
|
||||||
|
proc collectCT(gch: var TGcHeap)
|
||||||
|
proc IsOnStack(p: pointer): bool
|
||||||
|
proc forAllChildren(cell: PCell, op: TWalkOp)
|
||||||
|
proc collectCycles(gch: var TGcHeap)
|
||||||
|
|
||||||
|
proc reprAny(p: pointer, typ: PNimType): string {.compilerproc.}
|
||||||
|
# we need the prototype here for debugging purposes
|
||||||
|
|
||||||
proc prepareDealloc(cell: PCell) =
|
proc prepareDealloc(cell: PCell) =
|
||||||
if cell.typ.finalizer != nil:
|
if cell.typ.finalizer != nil:
|
||||||
|
|
@ -433,79 +535,95 @@ proc prepareDealloc(cell: PCell) =
|
||||||
else:
|
else:
|
||||||
memUsed = memUsed - cell.typ.size
|
memUsed = memUsed - cell.typ.size
|
||||||
|
|
||||||
proc setStackBottom(theStackBottom: pointer) {.compilerproc.} =
|
proc checkZCT(): bool =
|
||||||
stackBottom = theStackBottom
|
if recGcLock >= 1: return true # prevent endless recursion
|
||||||
|
|
||||||
proc initGC() =
|
|
||||||
# init the rt
|
|
||||||
CellSetInit(ct.zct)
|
|
||||||
CellSetInit(ct.at)
|
|
||||||
ct.stackLen = 0
|
|
||||||
ct.stackMax = 255
|
|
||||||
ct.stackCells = cast[PStackCells](gcAlloc((ct.stackMax+1) * sizeof(PCell)))
|
|
||||||
ct.mask = 0
|
|
||||||
new(gOutOfMem) # reserve space for the EOutOfMemory exception here!
|
|
||||||
assert(GC_invariant())
|
|
||||||
|
|
||||||
# forward declarations:
|
|
||||||
proc collectCT(ct: var TCountTables)
|
|
||||||
proc IsOnStack(p: pointer): bool
|
|
||||||
proc forAllChildren(cell: PCell, op: TWalkOp)
|
|
||||||
proc collectCycles()
|
|
||||||
|
|
||||||
proc reprAny(p: pointer, typ: PNimType): string {.compilerproc.}
|
|
||||||
# we need the prototype here for debugging purposes
|
|
||||||
|
|
||||||
proc outputCell(c: PCell) =
|
|
||||||
inc(recGcLock)
|
inc(recGcLock)
|
||||||
write(stdout, reprAny(cellToUsr(c), c.typ))
|
result = true
|
||||||
|
for i in 0..gch.zct.len-1:
|
||||||
|
var c = gch.zct.d[i]
|
||||||
|
if c.refcount > 0: # should be in the ZCT!
|
||||||
|
writeCell("wrong ZCT entry", c)
|
||||||
|
result = false
|
||||||
|
elif gch.zct.d[-c.refcount] != c:
|
||||||
|
writeCell("wrong ZCT position", c)
|
||||||
|
result = false
|
||||||
dec(recGcLock)
|
dec(recGcLock)
|
||||||
|
|
||||||
proc writeGraph() =
|
proc GC_invariant(): bool =
|
||||||
{.checkpoint.}
|
|
||||||
block:
|
|
||||||
inc(recGcLock)
|
|
||||||
for c in elements(ct.AT): outputCell(c)
|
|
||||||
dec(recGcLock)
|
|
||||||
|
|
||||||
proc checkRefc(): bool =
|
|
||||||
if recGcLock >= 1: return true # prevent endless recursion
|
if recGcLock >= 1: return true # prevent endless recursion
|
||||||
inc(recGcLock)
|
inc(recGcLock)
|
||||||
result = True
|
result = True
|
||||||
|
block checks:
|
||||||
|
if not checkZCT():
|
||||||
|
result = false
|
||||||
|
break checks
|
||||||
# set counters back to zero:
|
# set counters back to zero:
|
||||||
for c in elements(ct.AT):
|
for c in elements(gch.AT):
|
||||||
c.drefc = 0
|
var t = c.typ
|
||||||
for c in elements(ct.AT):
|
if t == nil or t.kind notin {tySequence, tyString, tyRef}:
|
||||||
|
writeCell("corrupt cell?", c)
|
||||||
|
result = false
|
||||||
|
break checks
|
||||||
|
when stressGC: c.drefc = 0
|
||||||
|
for c in elements(gch.AT):
|
||||||
forAllChildren(c, waDebugIncRef)
|
forAllChildren(c, waDebugIncRef)
|
||||||
for c in elements(ct.AT):
|
when stressGC:
|
||||||
if c.drefc > c.refcount - c.stackcount:
|
for c in elements(gch.AT):
|
||||||
|
var rc = c.refcount
|
||||||
|
if rc < 0: rc = 0
|
||||||
|
if c.drefc > rc + c.stackcount:
|
||||||
result = false # failed
|
result = false # failed
|
||||||
c_fprintf(c_stdout,
|
c_fprintf(c_stdout,
|
||||||
"broken cell: %p, refc: %ld, stack: %ld, real: %ld\n",
|
"broken cell: %p, refc: %ld, stack: %ld, real: %ld\n",
|
||||||
c, c.refcount, c.stackcount, c.drefc)
|
c, c.refcount, c.stackcount, c.drefc)
|
||||||
|
break checks
|
||||||
dec(recGcLock)
|
dec(recGcLock)
|
||||||
|
|
||||||
proc seqCheck(cell: PCell): bool =
|
when stressGC:
|
||||||
assert(cell.typ != nil)
|
proc GCdebugHook() =
|
||||||
if cell.typ.kind in {tySequence, tyString}:
|
if not GC_invariant():
|
||||||
result = cell.refcount - cell.stackcount <= 1
|
assert(false)
|
||||||
else:
|
|
||||||
result = true
|
dbgLineHook = GCdebugHook
|
||||||
|
|
||||||
|
proc setStackBottom(theStackBottom: pointer) {.compilerproc.} =
|
||||||
|
stackBottom = theStackBottom
|
||||||
|
|
||||||
|
proc initGC() =
|
||||||
|
when traceGC:
|
||||||
|
for i in low(TCellState)..high(TCellState): CellSetInit(states[i])
|
||||||
|
# init the rt
|
||||||
|
init(gch.zct)
|
||||||
|
CellSetInit(gch.at)
|
||||||
|
init(gch.stackCells)
|
||||||
|
gch.mask = 0
|
||||||
|
new(gOutOfMem) # reserve space for the EOutOfMemory exception here!
|
||||||
|
assert(GC_invariant())
|
||||||
|
|
||||||
proc decRef(cell: PCell) {.inline.} =
|
proc decRef(cell: PCell) {.inline.} =
|
||||||
assert(cell in ct.AT)
|
|
||||||
when defined(debugGC):
|
|
||||||
if cell.refcount == 0:
|
|
||||||
writePtr("decref broken", cellToUsr(cell))
|
|
||||||
assert(cell.refcount > 0) # this should be the case!
|
assert(cell.refcount > 0) # this should be the case!
|
||||||
assert(seqCheck(cell))
|
when stressGC: assert(cell in gch.AT)
|
||||||
dec(cell.refcount)
|
dec(cell.refcount)
|
||||||
if cell.refcount == 0:
|
if cell.refcount == 0:
|
||||||
incl(ct.zct, cell)
|
cell.refcount = -gch.zct.len
|
||||||
|
when stressGC: assert(cell notin gch.zct)
|
||||||
|
add(gch.zct, cell)
|
||||||
|
when stressGC: assert(checkZCT())
|
||||||
|
|
||||||
proc incRef(cell: PCell) {.inline.} =
|
proc incRef(cell: PCell) {.inline.} =
|
||||||
assert(seqCheck(cell))
|
var rc = cell.refcount
|
||||||
|
if rc <= 0:
|
||||||
|
# remove from zero count table:
|
||||||
|
when stressGC: assert(gch.zct.len > -rc)
|
||||||
|
when stressGC: assert(gch.zct.d[-rc] == cell)
|
||||||
|
gch.zct.d[-rc] = gch.zct.d[gch.zct.len-1]
|
||||||
|
gch.zct.d[-rc].refcount = rc
|
||||||
|
dec(gch.zct.len)
|
||||||
|
cell.refcount = 1
|
||||||
|
when stressGC: assert(checkZCT())
|
||||||
|
else:
|
||||||
inc(cell.refcount)
|
inc(cell.refcount)
|
||||||
|
when stressGC: assert(checkZCT())
|
||||||
|
|
||||||
proc asgnRef(dest: ppointer, src: pointer) =
|
proc asgnRef(dest: ppointer, src: pointer) =
|
||||||
# the code generator calls this proc!
|
# the code generator calls this proc!
|
||||||
|
|
@ -514,18 +632,18 @@ proc asgnRef(dest: ppointer, src: pointer) =
|
||||||
if src != nil: incRef(usrToCell(src))
|
if src != nil: incRef(usrToCell(src))
|
||||||
if dest^ != nil: decRef(usrToCell(dest^))
|
if dest^ != nil: decRef(usrToCell(dest^))
|
||||||
dest^ = src
|
dest^ = src
|
||||||
#assert(checkRefc())
|
when stressGC: assert(GC_invariant())
|
||||||
|
|
||||||
proc unsureAsgnRef(dest: ppointer, src: pointer) =
|
proc unsureAsgnRef(dest: ppointer, src: pointer) =
|
||||||
if not IsOnStack(dest):
|
if not IsOnStack(dest):
|
||||||
if src != nil: incRef(usrToCell(src))
|
if src != nil: incRef(usrToCell(src))
|
||||||
if dest^ != nil: decRef(usrToCell(dest^))
|
if dest^ != nil: decRef(usrToCell(dest^))
|
||||||
dest^ = src
|
dest^ = src
|
||||||
#assert(checkRefc())
|
when stressGC: assert(GC_invariant())
|
||||||
|
|
||||||
proc restore(cell: PCell) =
|
proc restore(cell: PCell) =
|
||||||
if cell notin ct.newAT:
|
if cell notin gch.newAT:
|
||||||
incl(ct.newAT, Cell)
|
incl(gch.newAT, Cell)
|
||||||
forAllChildren(cell, waCycleIncRef)
|
forAllChildren(cell, waCycleIncRef)
|
||||||
|
|
||||||
proc doOperation(p: pointer, op: TWalkOp) =
|
proc doOperation(p: pointer, op: TWalkOp) =
|
||||||
|
|
@ -536,19 +654,15 @@ proc doOperation(p: pointer, op: TWalkOp) =
|
||||||
of waNone: assert(false)
|
of waNone: assert(false)
|
||||||
of waRelease: decRef(cell) # DEAD CODE!
|
of waRelease: decRef(cell) # DEAD CODE!
|
||||||
of waZctDecRef:
|
of waZctDecRef:
|
||||||
assert(cell.refcount > 0)
|
decRef(cell)
|
||||||
assert(seqCheck(cell))
|
|
||||||
dec(cell.refcount)
|
|
||||||
if cell.refcount == 0:
|
|
||||||
incl(ct.newZCT, cell)
|
|
||||||
of waCycleDecRef:
|
of waCycleDecRef:
|
||||||
assert(cell.refcount != 0)
|
assert(cell.refcount > 0)
|
||||||
dec(cell.refcount)
|
dec(cell.refcount)
|
||||||
of waCycleIncRef:
|
of waCycleIncRef:
|
||||||
inc(cell.refcount) # restore proper reference counts!
|
inc(cell.refcount) # restore proper reference counts!
|
||||||
restore(cell)
|
restore(cell)
|
||||||
of waDebugIncRef:
|
of waDebugIncRef:
|
||||||
inc(cell.drefc)
|
when stressGC: inc(cell.drefc)
|
||||||
|
|
||||||
type
|
type
|
||||||
TByteArray = array[0..1000_0000, byte]
|
TByteArray = array[0..1000_0000, byte]
|
||||||
|
|
@ -590,16 +704,20 @@ proc forAllSlotsAux(dest: pointer, n: ptr TNimNode, op: TWalkOp) =
|
||||||
if m != nil: forAllSlotsAux(dest, m, op)
|
if m != nil: forAllSlotsAux(dest, m, op)
|
||||||
|
|
||||||
proc forAllChildrenAux(dest: Pointer, mt: PNimType, op: TWalkOp) =
|
proc forAllChildrenAux(dest: Pointer, mt: PNimType, op: TWalkOp) =
|
||||||
|
const
|
||||||
|
handledTypes = {tyArray, tyArrayConstr, tyOpenArray, tyRef,
|
||||||
|
tyString, tySequence, tyObject, tyPureObject, tyTuple}
|
||||||
var
|
var
|
||||||
d = cast[TAddress](dest)
|
d = cast[TAddress](dest)
|
||||||
if dest == nil: return # nothing to do
|
if dest == nil: return # nothing to do
|
||||||
case mt.Kind
|
case mt.Kind
|
||||||
of tyArray, tyArrayConstr, tyOpenArray:
|
of tyArray, tyArrayConstr, tyOpenArray:
|
||||||
|
if mt.base.kind in handledTypes:
|
||||||
for i in 0..(mt.size div mt.base.size)-1:
|
for i in 0..(mt.size div mt.base.size)-1:
|
||||||
forAllChildrenAux(cast[pointer](d +% i *% mt.base.size), mt.base, op)
|
forAllChildrenAux(cast[pointer](d +% i *% mt.base.size), mt.base, op)
|
||||||
of tyRef, tyString, tySequence: # leaf:
|
of tyRef, tyString, tySequence: # leaf:
|
||||||
doOperation(cast[ppointer](d)^, op)
|
doOperation(cast[ppointer](d)^, op)
|
||||||
of tyRecord, tyObject, tyTuple:
|
of tyObject, tyTuple, tyPureObject:
|
||||||
forAllSlotsAux(dest, mt.node, op)
|
forAllSlotsAux(dest, mt.node, op)
|
||||||
else: nil
|
else: nil
|
||||||
|
|
||||||
|
|
@ -608,6 +726,13 @@ proc forAllChildren(cell: PCell, op: TWalkOp) =
|
||||||
when defined(debugGC):
|
when defined(debugGC):
|
||||||
if cell.typ == nil:
|
if cell.typ == nil:
|
||||||
writeCell("cell has no type descriptor", cell)
|
writeCell("cell has no type descriptor", cell)
|
||||||
|
when traceGC:
|
||||||
|
if cell notin states[csAllocated]:
|
||||||
|
writeCell("cell has never been allocated!", cell)
|
||||||
|
if cell in states[csCycFreed]:
|
||||||
|
writeCell("cell has been freed by Cyc", cell)
|
||||||
|
if cell in states[csZctFreed]:
|
||||||
|
writeCell("cell has been freed by Zct", cell)
|
||||||
assert(cell.typ != nil)
|
assert(cell.typ != nil)
|
||||||
case cell.typ.Kind
|
case cell.typ.Kind
|
||||||
of tyRef: # common case
|
of tyRef: # common case
|
||||||
|
|
@ -625,36 +750,36 @@ proc forAllChildren(cell: PCell, op: TWalkOp) =
|
||||||
proc checkCollection() {.inline.} =
|
proc checkCollection() {.inline.} =
|
||||||
# checks if a collection should be done
|
# checks if a collection should be done
|
||||||
if recGcLock == 0:
|
if recGcLock == 0:
|
||||||
if memUsed >= rcThreshold or stressGC:
|
collectCT(gch)
|
||||||
collectCT(ct)
|
|
||||||
when defined(debugGC):
|
|
||||||
write(stdout, "threshold is now: ")
|
|
||||||
writeln(stdout, rcThreshold)
|
|
||||||
|
|
||||||
proc newObj(typ: PNimType, size: int): pointer =
|
proc newObj(typ: PNimType, size: int): pointer =
|
||||||
# generates a new object and sets its reference counter to 0
|
# generates a new object and sets its reference counter to 0
|
||||||
var
|
var
|
||||||
res: PCell
|
res: PCell
|
||||||
|
when stressGC: assert(checkZCT())
|
||||||
assert(typ.kind in {tyRef, tyString, tySequence})
|
assert(typ.kind in {tyRef, tyString, tySequence})
|
||||||
# check if we have to collect:
|
# check if we have to collect:
|
||||||
checkCollection()
|
checkCollection()
|
||||||
res = cast[PCell](Alloc0(size + sizeof(TCell)))
|
res = cast[PCell](Alloc0(size + sizeof(TCell)))
|
||||||
|
when stressGC: assert((cast[TAddress](res) and (MemAlignment-1)) == 0)
|
||||||
if res == nil: raiseOutOfMem()
|
if res == nil: raiseOutOfMem()
|
||||||
when defined(nimSize):
|
when defined(nimSize):
|
||||||
memUsed = memUsed + nimSize(res)
|
memUsed = memUsed + nimSize(res)
|
||||||
else:
|
else:
|
||||||
memUsed = memUsed + size
|
memUsed = memUsed + size
|
||||||
|
|
||||||
res.refcount = 0
|
|
||||||
# now it is buffered in the ZCT
|
# now it is buffered in the ZCT
|
||||||
res.typ = typ
|
res.typ = typ
|
||||||
incl(ct.zct, res) # its refcount is zero, so add it to the ZCT
|
res.refcount = -gch.zct.len
|
||||||
incl(ct.at, res) # add it to the any table too
|
add(gch.zct, res) # its refcount is zero, so add it to the ZCT
|
||||||
ct.mask = ct.mask or cast[TAddress](res)
|
incl(gch.at, res) # add it to the any table too
|
||||||
|
gch.mask = gch.mask or cast[TAddress](res)
|
||||||
when defined(debugGC):
|
when defined(debugGC):
|
||||||
writeCell("new cell", res)
|
when defined(logGC): writeCell("new cell", res)
|
||||||
assert(gcInvariant())
|
gcTrace(res, csAllocated)
|
||||||
result = cellToUsr(res)
|
result = cellToUsr(res)
|
||||||
|
assert(res.typ == typ)
|
||||||
|
when stressGC: assert(checkZCT())
|
||||||
|
|
||||||
proc newSeq(typ: PNimType, len: int): pointer =
|
proc newSeq(typ: PNimType, len: int): pointer =
|
||||||
# XXX: overflow checks!
|
# XXX: overflow checks!
|
||||||
|
|
@ -665,16 +790,19 @@ proc newSeq(typ: PNimType, len: int): pointer =
|
||||||
proc growObj(old: pointer, newsize: int): pointer =
|
proc growObj(old: pointer, newsize: int): pointer =
|
||||||
var
|
var
|
||||||
res, ol: PCell
|
res, ol: PCell
|
||||||
|
when stressGC: assert(checkZCT())
|
||||||
checkCollection()
|
checkCollection()
|
||||||
ol = usrToCell(old)
|
ol = usrToCell(old)
|
||||||
assert(ol.typ.kind in {tyString, tySequence})
|
assert(ol.typ.kind in {tyString, tySequence})
|
||||||
assert(seqCheck(ol))
|
|
||||||
when defined(nimSize):
|
when defined(nimSize):
|
||||||
memUsed = memUsed - nimSize(ol)
|
memUsed = memUsed - nimSize(ol)
|
||||||
else:
|
else:
|
||||||
memUsed = memUsed - ol.size # this is not exact
|
memUsed = memUsed - ol.size # this is not exact
|
||||||
# pity that we don't know the old size
|
# pity that we don't know the old size
|
||||||
res = cast[PCell](realloc(ol, newsize + sizeof(TCell)))
|
res = cast[PCell](realloc(ol, newsize + sizeof(TCell)))
|
||||||
|
#res = cast[PCell](gcAlloc(newsize + sizeof(TCell)))
|
||||||
|
#copyMem(res, ol, nimSize(ol))
|
||||||
|
assert((cast[TAddress](res) and (MemAlignment-1)) == 0)
|
||||||
when defined(nimSize):
|
when defined(nimSize):
|
||||||
memUsed = memUsed + nimSize(res)
|
memUsed = memUsed + nimSize(res)
|
||||||
else:
|
else:
|
||||||
|
|
@ -682,74 +810,69 @@ proc growObj(old: pointer, newsize: int): pointer =
|
||||||
|
|
||||||
if res != ol:
|
if res != ol:
|
||||||
if res == nil: raiseOutOfMem()
|
if res == nil: raiseOutOfMem()
|
||||||
excl(ct.zct, ol) # remove old pointer in any case:
|
if res.refcount <= 0:
|
||||||
# It may have a refcount > 0 and is still in the ZCT.
|
assert(gch.zct.d[-res.refcount] == ol)
|
||||||
# So do it safe here and remove it anyway.
|
gch.zct.d[-res.refcount] = res
|
||||||
excl(ct.at, ol)
|
excl(gch.at, ol)
|
||||||
if res.refcount == 0:
|
incl(gch.at, res)
|
||||||
# store new pointer in ZCT, if refcount == 0:
|
gch.mask = gch.mask or cast[TAddress](res)
|
||||||
incl(ct.zct, res)
|
when defined(logGC):
|
||||||
incl(ct.at, res)
|
|
||||||
ct.mask = ct.mask or cast[TAddress](res)
|
|
||||||
when defined(debugGC):
|
|
||||||
writeCell("growObj old cell", ol)
|
writeCell("growObj old cell", ol)
|
||||||
writeCell("growObj new cell", res)
|
writeCell("growObj new cell", res)
|
||||||
|
gcTrace(ol, csZctFreed)
|
||||||
|
gcTrace(res, csAllocated)
|
||||||
result = cellToUsr(res)
|
result = cellToUsr(res)
|
||||||
#assert(checkRefc())
|
when stressGC: assert(checkZCT())
|
||||||
|
|
||||||
proc collectCycles() =
|
proc collectCycles(gch: var TGcHeap) =
|
||||||
when defined(debugGC):
|
when defined(logGC):
|
||||||
echo("collecting cycles!\n")
|
c_fprintf(c_stdout, "collecting cycles!\n")
|
||||||
|
|
||||||
# step 1: pretend that any node is dead
|
# step 1: pretend that any node is dead
|
||||||
for c in elements(ct.at):
|
for c in elements(gch.at):
|
||||||
forallChildren(c, waCycleDecRef)
|
forallChildren(c, waCycleDecRef)
|
||||||
CellSetInit(ct.newAt)
|
CellSetInit(gch.newAt)
|
||||||
# step 2: restore life cells
|
# step 2: restore life cells
|
||||||
for c in elements(ct.at):
|
for c in elements(gch.at):
|
||||||
if c.refcount > 0: restore(c)
|
if c.refcount > 0: restore(c)
|
||||||
# step 3: free dead cells:
|
# step 3: free dead cells:
|
||||||
for cell in elements(ct.at):
|
for cell in elements(gch.at):
|
||||||
if cell.refcount == 0:
|
if cell.refcount == 0:
|
||||||
assert(cell notin ct.zct)
|
|
||||||
# We free an object that is part of a cycle here. Its children
|
# We free an object that is part of a cycle here. Its children
|
||||||
# may have been freed already. Thus the finalizer could access
|
# may have been freed already. Thus the finalizer could access
|
||||||
# garbage. To handle this case properly we need two passes for
|
# garbage. To handle this case properly we need two passes for
|
||||||
# freeing here which is too expensive. We just don't call the
|
# freeing here which is too expensive. We just don't call the
|
||||||
# finalizer for now. YYY: Any better ideas?
|
# finalizer for now. YYY: Any better ideas?
|
||||||
prepareDealloc(cell)
|
prepareDealloc(cell)
|
||||||
dealloc(cell)
|
gcTrace(cell, csCycFreed)
|
||||||
when defined(debugGC):
|
when defined(logGC):
|
||||||
writeCell("cycle collector dealloc cell", cell)
|
writeCell("cycle collector dealloc cell", cell)
|
||||||
CellSetDeinit(ct.at)
|
when reallyDealloc: dealloc(cell)
|
||||||
ct.at = ct.newAt
|
CellSetDeinit(gch.at)
|
||||||
#ct.newAt = nil
|
gch.at = gch.newAt
|
||||||
|
|
||||||
proc gcMark(p: pointer) =
|
proc gcMark(gch: var TGcHeap, p: pointer) =
|
||||||
# the addresses are not as objects on the stack, so turn them to objects:
|
# the addresses are not as objects on the stack, so turn them to objects:
|
||||||
var cell = usrToCell(p)
|
var cell = usrToCell(p)
|
||||||
var c = cast[TAddress](cell)
|
var c = cast[TAddress](cell)
|
||||||
if ((c and ct.mask) == c) and cell in ct.at:
|
if ((c and gch.mask) == c) and cell in gch.at:
|
||||||
# is the page that p "points to" in the AT? (All allocated pages are
|
# is the page that p "points to" in the AT? (All allocated pages are
|
||||||
# always in the AT)
|
# always in the AT)
|
||||||
inc(cell.refcount)
|
incRef(cell)
|
||||||
inc(cell.stackcount)
|
when stressGC: inc(cell.stackcount)
|
||||||
addStackCell(ct, cell)
|
add(gch.stackCells, cell)
|
||||||
|
|
||||||
proc unmarkStackAndRegisters() =
|
proc unmarkStackAndRegisters(gch: var TGcHeap) =
|
||||||
for i in 0 .. ct.stackLen-1:
|
when stressGC: assert(checkZCT())
|
||||||
var cell = ct.stackCells[i]
|
for i in 0 .. gch.stackCells.len-1:
|
||||||
|
var cell = gch.stackCells.d[i]
|
||||||
assert(cell.refcount > 0)
|
assert(cell.refcount > 0)
|
||||||
when defined(debugGC):
|
when stressGC:
|
||||||
if cell.stackcount == 0:
|
|
||||||
writeGraph()
|
|
||||||
writePtr("broken stackcount", cellToUsr(cell))
|
|
||||||
assert(cell.stackcount > 0)
|
assert(cell.stackcount > 0)
|
||||||
dec(cell.refcount)
|
|
||||||
dec(cell.stackcount)
|
dec(cell.stackcount)
|
||||||
if cell.refcount == 0:
|
decRef(cell)
|
||||||
incl(ct.zct, cell)
|
gch.stackCells.len = 0 # reset to zero
|
||||||
ct.stackLen = 0 # reset to zero
|
when stressGC: assert(checkZCT())
|
||||||
|
|
||||||
# ----------------- stack management --------------------------------------
|
# ----------------- stack management --------------------------------------
|
||||||
# inspired from Smart Eiffel (c)
|
# inspired from Smart Eiffel (c)
|
||||||
|
|
@ -765,7 +888,7 @@ when defined(sparc): # For SPARC architecture.
|
||||||
stackTop: array[0..1, pointer]
|
stackTop: array[0..1, pointer]
|
||||||
result = p >= addr(stackTop[0]) and p <= stackBottom
|
result = p >= addr(stackTop[0]) and p <= stackBottom
|
||||||
|
|
||||||
proc markStackAndRegisters() =
|
proc markStackAndRegisters(gch: var TGcHeap) =
|
||||||
when defined(sparcv9):
|
when defined(sparcv9):
|
||||||
asm " flushw"
|
asm " flushw"
|
||||||
else:
|
else:
|
||||||
|
|
@ -780,7 +903,7 @@ when defined(sparc): # For SPARC architecture.
|
||||||
sp = addr(stackTop[0])
|
sp = addr(stackTop[0])
|
||||||
# Addresses decrease as the stack grows.
|
# Addresses decrease as the stack grows.
|
||||||
while sp <= max:
|
while sp <= max:
|
||||||
gcMark(sp^)
|
gcMark(gch, sp^)
|
||||||
sp = cast[ppointer](cast[TAddress](sp) +% sizeof(pointer))
|
sp = cast[ppointer](cast[TAddress](sp) +% sizeof(pointer))
|
||||||
|
|
||||||
elif defined(ELATE):
|
elif defined(ELATE):
|
||||||
|
|
@ -802,7 +925,7 @@ elif defined(hppa) or defined(hp9000) or defined(hp9000s300) or
|
||||||
# a little hack to get the size of a TJmpBuf in the generated C code
|
# a little hack to get the size of a TJmpBuf in the generated C code
|
||||||
# in a platform independant way
|
# in a platform independant way
|
||||||
|
|
||||||
proc markStackAndRegisters() =
|
proc markStackAndRegisters(gch: var TGcHeap) =
|
||||||
var
|
var
|
||||||
max = stackBottom
|
max = stackBottom
|
||||||
registers: C_JmpBuf # The jmp_buf buffer is in the C stack.
|
registers: C_JmpBuf # The jmp_buf buffer is in the C stack.
|
||||||
|
|
@ -814,7 +937,7 @@ elif defined(hppa) or defined(hp9000) or defined(hp9000s300) or
|
||||||
# sp will traverse the JMP_BUF as well (jmp_buf size is added,
|
# sp will traverse the JMP_BUF as well (jmp_buf size is added,
|
||||||
# otherwise sp would be below the registers structure).
|
# otherwise sp would be below the registers structure).
|
||||||
while sp >= max:
|
while sp >= max:
|
||||||
gcMark(sp^)
|
gcMark(gch, sp^)
|
||||||
sp = cast[ppointer](cast[TAddress](sp) -% sizeof(pointer))
|
sp = cast[ppointer](cast[TAddress](sp) -% sizeof(pointer))
|
||||||
|
|
||||||
else:
|
else:
|
||||||
|
|
@ -826,7 +949,7 @@ else:
|
||||||
stackTop: array [0..1, pointer]
|
stackTop: array [0..1, pointer]
|
||||||
result = p >= addr(stackTop[0]) and p <= stackBottom
|
result = p >= addr(stackTop[0]) and p <= stackBottom
|
||||||
|
|
||||||
proc markStackAndRegisters() =
|
proc markStackAndRegisters(gch: var TGcHeap) =
|
||||||
var
|
var
|
||||||
max = stackBottom
|
max = stackBottom
|
||||||
registers: C_JmpBuf # The jmp_buf buffer is in the C stack.
|
registers: C_JmpBuf # The jmp_buf buffer is in the C stack.
|
||||||
|
|
@ -835,63 +958,58 @@ else:
|
||||||
c_setjmp(registers) # To fill the C stack with registers.
|
c_setjmp(registers) # To fill the C stack with registers.
|
||||||
sp = cast[ppointer](addr(registers))
|
sp = cast[ppointer](addr(registers))
|
||||||
while sp <= max:
|
while sp <= max:
|
||||||
gcMark(sp^)
|
gcMark(gch, sp^)
|
||||||
sp = cast[ppointer](cast[TAddress](sp) +% sizeof(pointer))
|
sp = cast[ppointer](cast[TAddress](sp) +% sizeof(pointer))
|
||||||
|
|
||||||
# ----------------------------------------------------------------------------
|
# ----------------------------------------------------------------------------
|
||||||
# end of non-portable code
|
# end of non-portable code
|
||||||
# ----------------------------------------------------------------------------
|
# ----------------------------------------------------------------------------
|
||||||
|
|
||||||
proc CollectZCT =
|
proc CollectZCT(gch: var TGcHeap) =
|
||||||
CellSetInit(ct.newZCT)
|
while gch.zct.len > 0:
|
||||||
for c in elements(ct.zct):
|
var c = gch.zct.d[0]
|
||||||
if c.refcount == 0:
|
assert(c.refcount <= 0)
|
||||||
# if != 0 the reference count has been increased, so this does not
|
# remove from ZCT:
|
||||||
# belong to the ZCT. We simply do nothing - it won't appear in the newZCT
|
gch.zct.d[0] = gch.zct.d[gch.zct.len-1]
|
||||||
# anyway.
|
gch.zct.d[0].refcount = 0
|
||||||
|
dec(gch.zct.len)
|
||||||
# We are about to free the object, call the finalizer BEFORE its
|
# We are about to free the object, call the finalizer BEFORE its
|
||||||
# children are deleted as well, because otherwise the finalizer may
|
# children are deleted as well, because otherwise the finalizer may
|
||||||
# access invalid memory. This is done by prepareDealloc():
|
# access invalid memory. This is done by prepareDealloc():
|
||||||
|
gcTrace(c, csZctFreed)
|
||||||
prepareDealloc(c)
|
prepareDealloc(c)
|
||||||
forAllChildren(c, waZctDecRef)
|
forAllChildren(c, waZctDecRef)
|
||||||
assert(c.refcount == 0) # should still be zero
|
excl(gch.at, c)
|
||||||
excl(ct.at, c)
|
when defined(logGC):
|
||||||
excl(ct.newZCT, c) # BUGFIX
|
|
||||||
when defined(debugGC):
|
|
||||||
writeCell("zct dealloc cell", c)
|
writeCell("zct dealloc cell", c)
|
||||||
dealloc(c)
|
#when defined(debugGC) and defined(nimSize): zeroMem(c, nimSize(c))
|
||||||
CellSetDeinit(ct.zct)
|
when reallyDealloc: dealloc(c)
|
||||||
ct.zct = ct.newZCT
|
|
||||||
#ct.newZCT = nil
|
|
||||||
|
|
||||||
proc collectCT(ct: var TCountTables) =
|
proc collectCT(gch: var TGcHeap) =
|
||||||
when defined(debugGC):
|
when defined(logGC):
|
||||||
c_fprintf(c_stdout, "collecting zero count table; stack size: %ld\n",
|
c_fprintf(c_stdout, "collecting zero count table; stack size: %ld\n",
|
||||||
stackSize())
|
stackSize())
|
||||||
markStackAndRegisters()
|
when stressGC: assert(checkZCT())
|
||||||
assert(GC_invariant())
|
if gch.zct.len >= ZctThreshold or memUsed >= cycleThreshold or stressGC:
|
||||||
while True:
|
markStackAndRegisters(gch)
|
||||||
collectZCT()
|
when stressGC: assert(GC_invariant())
|
||||||
if ct.zct.counter == 0: break
|
collectZCT(gch)
|
||||||
# ``counter`` counts the pages, but zero pages means zero cells
|
when stressGC: assert(GC_invariant())
|
||||||
|
assert(gch.zct.len == 0)
|
||||||
when defined(cycleGC):
|
when defined(cycleGC):
|
||||||
# still over the cycle threshold?
|
|
||||||
if memUsed >= cycleThreshold or stressGC:
|
if memUsed >= cycleThreshold or stressGC:
|
||||||
# collect the cyclic things:
|
when defined(logGC):
|
||||||
assert(ct.zct.counter == 0)
|
c_fprintf(c_stdout, "collecting cycles; memory used: %ld\n", memUsed)
|
||||||
assert(GC_invariant())
|
collectCycles(gch)
|
||||||
collectCycles()
|
cycleThreshold = max(InitialCycleThreshold, memUsed * cycleIncrease)
|
||||||
|
when defined(logGC):
|
||||||
# recompute the thresholds:
|
c_fprintf(c_stdout, "now used: %ld; threshold: %ld\n",
|
||||||
rcThreshold = (memUsed div RC_increase + 1) * RC_Increase
|
memUsed, cycleThreshold)
|
||||||
cycleThreshold = memUsed * cycleIncrease
|
unmarkStackAndRegisters(gch)
|
||||||
|
when stressGC: assert(GC_invariant())
|
||||||
assert(GC_invariant())
|
|
||||||
unmarkStackAndRegisters()
|
|
||||||
|
|
||||||
proc GC_fullCollect() =
|
proc GC_fullCollect() =
|
||||||
var oldThreshold = cycleThreshold
|
var oldThreshold = cycleThreshold
|
||||||
cycleThreshold = 0 # forces cycle collection
|
cycleThreshold = 0 # forces cycle collection
|
||||||
collectCT(ct)
|
collectCT(gch)
|
||||||
cycleThreshold = oldThreshold
|
cycleThreshold = oldThreshold
|
||||||
|
|
|
||||||
51
lib/hti.nim
51
lib/hti.nim
|
|
@ -10,29 +10,38 @@
|
||||||
type # This should be he same as ast.TTypeKind
|
type # This should be he same as ast.TTypeKind
|
||||||
# some enum fields are not used at runtime
|
# some enum fields are not used at runtime
|
||||||
TNimKind = enum
|
TNimKind = enum
|
||||||
tyNone, tyBool, tyChar,
|
tyNone, # 0
|
||||||
tyEmptySet, tyArrayConstr, tyNil, tyRecordConstr,
|
tyBool, # 1
|
||||||
tyGeneric,
|
tyChar, # 2
|
||||||
tyGenericInst,
|
tyEmptySet, # 3
|
||||||
tyGenericParam,
|
tyArrayConstr, # 4
|
||||||
tyEnum, tyAnyEnum,
|
tyNil, # 5
|
||||||
tyArray,
|
tyGeneric, # 6
|
||||||
tyRecord,
|
tyGenericInst, # 7
|
||||||
tyObject,
|
tyGenericParam, # 8
|
||||||
tyTuple,
|
tyEnum, # 9
|
||||||
tySet,
|
tyAnyEnum, # 10
|
||||||
tyRange,
|
tyArray, # 11
|
||||||
tyPtr, tyRef,
|
tyObject, # 12
|
||||||
tyVar,
|
tyTuple, # 13
|
||||||
tySequence,
|
tySet, # 14
|
||||||
tyProc,
|
tyRange, # 15
|
||||||
tyPointer, tyOpenArray,
|
tyPtr, # 16
|
||||||
tyString, tyCString, tyForward,
|
tyRef, # 17
|
||||||
|
tyVar, # 18
|
||||||
|
tySequence, # 19
|
||||||
|
tyProc, # 20
|
||||||
|
tyPointer, # 21
|
||||||
|
tyOpenArray, # 22
|
||||||
|
tyString, # 23
|
||||||
|
tyCString, # 24
|
||||||
|
tyForward, # 25
|
||||||
tyInt, tyInt8, tyInt16, tyInt32, tyInt64,
|
tyInt, tyInt8, tyInt16, tyInt32, tyInt64,
|
||||||
tyFloat, tyFloat32, tyFloat64, tyFloat128
|
tyFloat, tyFloat32, tyFloat64, tyFloat128,
|
||||||
|
tyPureObject # 35: signals that object has no `n_type` field
|
||||||
|
|
||||||
TNimNodeKind = enum nkNone, nkSlot, nkList, nkCase
|
TNimNodeKind = enum nkNone, nkSlot, nkList, nkCase
|
||||||
TNimNode {.compilerproc.} = record
|
TNimNode {.compilerproc, final.} = object
|
||||||
kind: TNimNodeKind
|
kind: TNimNodeKind
|
||||||
offset: int
|
offset: int
|
||||||
typ: ptr TNimType
|
typ: ptr TNimType
|
||||||
|
|
@ -40,7 +49,7 @@ type # This should be he same as ast.TTypeKind
|
||||||
len: int
|
len: int
|
||||||
sons: ptr array [0..0x7fff, ptr TNimNode]
|
sons: ptr array [0..0x7fff, ptr TNimNode]
|
||||||
|
|
||||||
TNimType {.compilerproc.} = record
|
TNimType {.compilerproc, final.} = object
|
||||||
size: int
|
size: int
|
||||||
kind: TNimKind
|
kind: TNimKind
|
||||||
base: ptr TNimType
|
base: ptr TNimType
|
||||||
|
|
|
||||||
|
|
@ -10,8 +10,7 @@
|
||||||
# 64 bit integers for platforms that don't have those
|
# 64 bit integers for platforms that don't have those
|
||||||
|
|
||||||
type
|
type
|
||||||
IInt64 = record # "internal" int64
|
IInt64 = tuple[lo, hi: int32]
|
||||||
lo, hi: int32
|
|
||||||
|
|
||||||
proc cmpI64(x, y: IInt64): int32 {.compilerproc.} =
|
proc cmpI64(x, y: IInt64): int32 {.compilerproc.} =
|
||||||
result = x.hi -% y.hi
|
result = x.hi -% y.hi
|
||||||
|
|
|
||||||
214
lib/math.nim
214
lib/math.nim
|
|
@ -1,75 +1,22 @@
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
# Nimrod's Runtime Library
|
# Nimrod's Runtime Library
|
||||||
# (c) Copyright 2006 Andreas Rumpf
|
# (c) Copyright 2008 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.
|
||||||
#
|
#
|
||||||
|
|
||||||
|
## Basic math routines for Nimrod.
|
||||||
|
## This module is available for the ECMAScript target.
|
||||||
# math routines
|
|
||||||
|
|
||||||
# interface
|
|
||||||
|
|
||||||
{.push debugger:off .} # the user does not want to trace a part
|
{.push debugger:off .} # the user does not want to trace a part
|
||||||
# of the standard library!
|
# of the standard library!
|
||||||
|
|
||||||
{.push checks:off, line_dir:off, stack_trace:off.}
|
{.push checks:off, line_dir:off, stack_trace:off.}
|
||||||
|
|
||||||
proc nextPowerOfTwo*(x: int): int
|
when defined(Posix):
|
||||||
## returns the nearest power of two, so that
|
{.passl: "-lm".}
|
||||||
## result**2 >= x > (result-1)**2.
|
|
||||||
proc isPowerOfTwo*(x: int): bool {.noSideEffect.}
|
|
||||||
## returns true, if x is a power of two, false otherwise.
|
|
||||||
## Negative numbers are not a power of two.
|
|
||||||
proc countBits*(n: int32): int {.noSideEffect.}
|
|
||||||
## counts the set bits in `n`.
|
|
||||||
|
|
||||||
proc random*(max: int): int
|
|
||||||
## returns a random number in the range 0..max-1. The sequence of
|
|
||||||
## random number is always the same, unless `randomize` is called
|
|
||||||
## which initializes the random number generator with a "random"
|
|
||||||
## number, i.e. a tickcount.
|
|
||||||
proc randomize*()
|
|
||||||
## initializes the random number generator with a "random"
|
|
||||||
## number, i.e. a tickcount.
|
|
||||||
|
|
||||||
proc sqrt*(x: float): float {.importc: "sqrt", header: "<math.h>".}
|
|
||||||
## computes the square root of `x`.
|
|
||||||
|
|
||||||
proc ln*(x: float): float {.importc: "log", header: "<math.h>".}
|
|
||||||
## computes ln(x).
|
|
||||||
proc exp*(x: float): float {.importc: "exp", header: "<math.h>".}
|
|
||||||
## computes e**x.
|
|
||||||
|
|
||||||
proc frexp*(x: float, exponent: var int): float {.
|
|
||||||
importc: "frexp", header: "<math.h>".}
|
|
||||||
## Split a number into mantissa and exponent.
|
|
||||||
## `frexp` calculates the mantissa m (a float greater than or equal to 0.5
|
|
||||||
## and less than 1) and the integer value n such that `x` (the original
|
|
||||||
## float value) equals m * 2**n. frexp stores n in `exponent` and returns
|
|
||||||
## m.
|
|
||||||
|
|
||||||
proc arccos*(x: float): float {.importc: "acos", header: "<math.h>".}
|
|
||||||
proc arcsin*(x: float): float {.importc: "asin", header: "<math.h>".}
|
|
||||||
proc arctan*(x: float): float {.importc: "atan", header: "<math.h>".}
|
|
||||||
proc arctan2*(y, x: float): float {.importc: "atan2", header: "<math.h>".}
|
|
||||||
## Calculate the arc tangent of `y` / `x`.
|
|
||||||
## `atan2` returns the arc tangent of `y` / `x`; it produces correct
|
|
||||||
## results even when the resulting angle is near pi/2 or -pi/2
|
|
||||||
## (`x` near 0).
|
|
||||||
|
|
||||||
proc cos*(x: float): float {.importc: "cos", header: "<math.h>".}
|
|
||||||
proc cosh*(x: float): float {.importc: "cosh", header: "<math.h>".}
|
|
||||||
proc hypot*(x: float): float {.importc: "hypot", header: "<math.h>".}
|
|
||||||
proc log10*(x: float): float {.importc: "log10", header: "<math.h>".}
|
|
||||||
proc sinh*(x: float): float {.importc: "sinh", header: "<math.h>".}
|
|
||||||
proc tan*(x: float): float {.importc: "tan", header: "<math.h>".}
|
|
||||||
proc tanh*(x: float): float {.importc: "tanh", header: "<math.h>".}
|
|
||||||
proc pow*(x, y: float): float {.importc: "pos", header: "<math.h>".}
|
|
||||||
## computes x to power raised of y.
|
|
||||||
|
|
||||||
type
|
type
|
||||||
TFloatClass* = enum ## describes the class a floating point value belongs to.
|
TFloatClass* = enum ## describes the class a floating point value belongs to.
|
||||||
|
|
@ -82,34 +29,11 @@ type
|
||||||
fcInf, ## value is positive infinity
|
fcInf, ## value is positive infinity
|
||||||
fcNegInf ## value is negative infinity
|
fcNegInf ## value is negative infinity
|
||||||
|
|
||||||
proc classify*(x: float): TFloatClass
|
proc classify*(x: float): TFloatClass =
|
||||||
## classifies a floating point value. Returns `x`'s class as specified by
|
## classifies a floating point value. Returns `x`'s class as specified by
|
||||||
## `TFloatClass`
|
## `TFloatClass`.
|
||||||
|
|
||||||
# implementation
|
# ECMAScript and most C compilers have no classify:
|
||||||
|
|
||||||
include cntbits
|
|
||||||
|
|
||||||
proc nextPowerOfTwo(x: int): int =
|
|
||||||
result = x - 1
|
|
||||||
when defined(cpu64):
|
|
||||||
result = result or (result shr 32)
|
|
||||||
result = result or (result shr 16)
|
|
||||||
result = result or (result shr 8)
|
|
||||||
result = result or (result shr 4)
|
|
||||||
result = result or (result shr 2)
|
|
||||||
result = result or (result shr 1)
|
|
||||||
Inc(result)
|
|
||||||
|
|
||||||
# C procs:
|
|
||||||
proc gettime(dummy: ptr cint): cint {.
|
|
||||||
importc: "time", header: "<time.h>".}
|
|
||||||
proc srand(seed: cint) {.
|
|
||||||
importc: "srand", nodecl.}
|
|
||||||
proc rand(): cint {.importc: "rand", nodecl.}
|
|
||||||
|
|
||||||
# most C compilers have no classify:
|
|
||||||
proc classify(x: float): TFloatClass =
|
|
||||||
if x == 0.0:
|
if x == 0.0:
|
||||||
if 1.0/x == 1.0/0.0:
|
if 1.0/x == 1.0/0.0:
|
||||||
return fcZero
|
return fcZero
|
||||||
|
|
@ -122,10 +46,130 @@ proc classify(x: float): TFloatClass =
|
||||||
return fcNormal
|
return fcNormal
|
||||||
# XXX: fcSubnormal is not detected!
|
# XXX: fcSubnormal is not detected!
|
||||||
|
|
||||||
|
|
||||||
|
proc isPowerOfTwo*(x: int): bool {.noSideEffect.} =
|
||||||
|
## returns true, if x is a power of two, false otherwise.
|
||||||
|
## Negative numbers are not a power of two.
|
||||||
|
return (x and -x) == x
|
||||||
|
|
||||||
|
proc nextPowerOfTwo*(x: int): int =
|
||||||
|
## returns the nearest power of two, so that
|
||||||
|
## result**2 >= x > (result-1)**2.
|
||||||
|
result = x - 1
|
||||||
|
when defined(cpu64):
|
||||||
|
result = result or (result shr 32)
|
||||||
|
result = result or (result shr 16)
|
||||||
|
result = result or (result shr 8)
|
||||||
|
result = result or (result shr 4)
|
||||||
|
result = result or (result shr 2)
|
||||||
|
result = result or (result shr 1)
|
||||||
|
Inc(result)
|
||||||
|
|
||||||
|
proc countBits*(n: int32): int {.noSideEffect.}
|
||||||
|
## counts the set bits in `n`.
|
||||||
|
|
||||||
|
include cntbits
|
||||||
|
|
||||||
|
|
||||||
|
when not defined(ECMAScript):
|
||||||
|
proc random*(max: int): int
|
||||||
|
## returns a random number in the range 0..max-1. The sequence of
|
||||||
|
## random number is always the same, unless `randomize` is called
|
||||||
|
## which initializes the random number generator with a "random"
|
||||||
|
## number, i.e. a tickcount.
|
||||||
|
proc randomize*()
|
||||||
|
## initializes the random number generator with a "random"
|
||||||
|
## number, i.e. a tickcount. Note: Does nothing for the ECMAScript target,
|
||||||
|
## as ECMAScript does not support this.
|
||||||
|
|
||||||
|
proc sqrt*(x: float): float {.importc: "sqrt", header: "<math.h>".}
|
||||||
|
## computes the square root of `x`.
|
||||||
|
|
||||||
|
proc ln*(x: float): float {.importc: "log", header: "<math.h>".}
|
||||||
|
## computes ln(x).
|
||||||
|
proc log10*(x: float): float {.importc: "log10", header: "<math.h>".}
|
||||||
|
proc log2*(x: float): float = return ln(x) / ln(2.0)
|
||||||
|
proc exp*(x: float): float {.importc: "exp", header: "<math.h>".}
|
||||||
|
## computes e**x.
|
||||||
|
|
||||||
|
proc frexp*(x: float, exponent: var int): float {.
|
||||||
|
importc: "frexp", header: "<math.h>".}
|
||||||
|
## Split a number into mantissa and exponent.
|
||||||
|
## `frexp` calculates the mantissa m (a float greater than or equal to 0.5
|
||||||
|
## and less than 1) and the integer value n such that `x` (the original
|
||||||
|
## float value) equals m * 2**n. frexp stores n in `exponent` and returns
|
||||||
|
## m.
|
||||||
|
|
||||||
|
proc round*(x: float): int {.importc: "lrint", nodecl.}
|
||||||
|
## converts a float to an int by rounding.
|
||||||
|
|
||||||
|
proc arccos*(x: float): float {.importc: "acos", header: "<math.h>".}
|
||||||
|
proc arcsin*(x: float): float {.importc: "asin", header: "<math.h>".}
|
||||||
|
proc arctan*(x: float): float {.importc: "atan", header: "<math.h>".}
|
||||||
|
proc arctan2*(y, x: float): float {.importc: "atan2", header: "<math.h>".}
|
||||||
|
## Calculate the arc tangent of `y` / `x`.
|
||||||
|
## `atan2` returns the arc tangent of `y` / `x`; it produces correct
|
||||||
|
## results even when the resulting angle is near pi/2 or -pi/2
|
||||||
|
## (`x` near 0).
|
||||||
|
|
||||||
|
proc cos*(x: float): float {.importc: "cos", header: "<math.h>".}
|
||||||
|
proc cosh*(x: float): float {.importc: "cosh", header: "<math.h>".}
|
||||||
|
proc hypot*(x, y: float): float {.importc: "hypot", header: "<math.h>".}
|
||||||
|
## same as ``sqrt(x*x + y*y)``.
|
||||||
|
|
||||||
|
proc sinh*(x: float): float {.importc: "sinh", header: "<math.h>".}
|
||||||
|
proc tan*(x: float): float {.importc: "tan", header: "<math.h>".}
|
||||||
|
proc tanh*(x: float): float {.importc: "tanh", header: "<math.h>".}
|
||||||
|
proc pow*(x, y: float): float {.importc: "pow", header: "<math.h>".}
|
||||||
|
## computes x to power raised of y.
|
||||||
|
|
||||||
|
# C procs:
|
||||||
|
proc gettime(dummy: ptr cint): cint {.importc: "time", header: "<time.h>".}
|
||||||
|
proc srand(seed: cint) {.importc: "srand", nodecl.}
|
||||||
|
proc rand(): cint {.importc: "rand", nodecl.}
|
||||||
|
|
||||||
proc randomize() = srand(gettime(nil))
|
proc randomize() = srand(gettime(nil))
|
||||||
proc random(max: int): int = return rand() mod max
|
proc random(max: int): int = return rand() mod max
|
||||||
|
|
||||||
proc isPowerOfTwo(x: int): bool = return (x and -x) == x
|
else:
|
||||||
|
proc mathrandom(): float {.importc: "Math.random", nodecl.}
|
||||||
|
proc mathfloor(x: float): float {.importc: "Math.floor", nodecl.}
|
||||||
|
proc random*(max: int): int = return mathfloor(mathrandom() * max)
|
||||||
|
proc randomize*() = nil
|
||||||
|
|
||||||
|
proc sqrt*(x: float): float {.importc: "Math.sqrt", nodecl.}
|
||||||
|
proc ln*(x: float): float {.importc: "Math.log", nodecl.}
|
||||||
|
proc log10*(x: float): float = return ln(x) / ln(10.0)
|
||||||
|
proc log2*(x: float): float = return ln(x) / ln(2.0)
|
||||||
|
|
||||||
|
proc exp*(x: float): float {.importc: "Math.exp", nodecl.}
|
||||||
|
proc round*(x: float): int {.importc: "Math.round", nodecl.}
|
||||||
|
proc pow*(x, y: float): float {.importc: "Math.pow", nodecl.}
|
||||||
|
|
||||||
|
proc frexp*(x: float, exponent: var int): float =
|
||||||
|
if x == 0.0:
|
||||||
|
exponent = 0.0
|
||||||
|
result = 0.0
|
||||||
|
elif x < 0.0:
|
||||||
|
result = -frexp(-x, exponent)
|
||||||
|
else:
|
||||||
|
var ex = mathfloor(log2(x))
|
||||||
|
exponent = round(ex)
|
||||||
|
result = x / pow(2.0, ex)
|
||||||
|
|
||||||
|
proc arccos*(x: float): float {.importc: "Math.acos", nodecl.}
|
||||||
|
proc arcsin*(x: float): float {.importc: "Math.asin", nodecl.}
|
||||||
|
proc arctan*(x: float): float {.importc: "Math.atan", nodecl.}
|
||||||
|
proc arctan2*(y, x: float): float {.importc: "Math.atan2", nodecl.}
|
||||||
|
|
||||||
|
proc cos*(x: float): float {.importc: "Math.cos", nodecl.}
|
||||||
|
proc cosh*(x: float): float = return (exp(x)+exp(-x))*0.5
|
||||||
|
proc hypot*(x, y: float): float = return sqrt(x*x + y*y)
|
||||||
|
proc sinh*(x: float): float = return (exp(x)-exp(-x))*0.5
|
||||||
|
proc tan*(x: float): float {.importc: "Math.tan", nodecl.}
|
||||||
|
proc tanh*(x: float): float =
|
||||||
|
var y = exp(2.0*x)
|
||||||
|
return (y-1.0)/(y+1.0)
|
||||||
|
|
||||||
{.pop.}
|
{.pop.}
|
||||||
{.pop.}
|
{.pop.}
|
||||||
|
|
|
||||||
201
lib/memman.nim
201
lib/memman.nim
|
|
@ -37,24 +37,24 @@ const
|
||||||
realFli = MaxFli - fliOffset
|
realFli = MaxFli - fliOffset
|
||||||
|
|
||||||
type
|
type
|
||||||
TFreePtr = record
|
TFreePtr {.final.} = object
|
||||||
prev, next: PBhdr
|
prev, next: PBhdr
|
||||||
Pbhdr = ptr Tbhdr
|
Pbhdr = ptr Tbhdr
|
||||||
Tbhdr = record
|
Tbhdr {.final.} = object
|
||||||
prevHdr: Pbhdr # this is just valid if the first bit of size is set
|
prevHdr: Pbhdr # this is just valid if the first bit of size is set
|
||||||
size: int # the size is stored in bytes
|
size: int # the size is stored in bytes
|
||||||
# bit 0 indicates whether the block is used and
|
# bit 0 indicates whether the block is used and
|
||||||
# bit 1 allows to know whether the previous block is free
|
# bit 1 allows to know whether the previous block is free
|
||||||
freePtr: TFreePtr # at this offset bhdr.buffer starts (was a union in the
|
freePtr: TFreePtr # at this offset bhdr.buffer starts (was a union in the
|
||||||
# C version)
|
# C version)
|
||||||
TAreaInfo = record # This structure is embedded at the beginning of each
|
TAreaInfo {.final.} = object # This structure is embedded at the beginning
|
||||||
# area, giving us enough information to cope with a set
|
# of each area, giving us enough information
|
||||||
# of areas
|
# to cope with a set of areas
|
||||||
theEnd: Pbhdr
|
theEnd: Pbhdr
|
||||||
next: PAreaInfo
|
next: PAreaInfo
|
||||||
PAreaInfo = ptr TAreaInfo
|
PAreaInfo = ptr TAreaInfo
|
||||||
|
|
||||||
TLSF = record
|
TLSF {.final.} = object
|
||||||
tlsf_signature: int32 # the TLSF's structure signature
|
tlsf_signature: int32 # the TLSF's structure signature
|
||||||
usedSize, maxSize: int
|
usedSize, maxSize: int
|
||||||
areaHead: PAreaInfo # A linked list holding all the existing areas
|
areaHead: PAreaInfo # A linked list holding all the existing areas
|
||||||
|
|
@ -147,6 +147,7 @@ elif defined(windows):
|
||||||
if result == nil: raiseOutOfMem()
|
if result == nil: raiseOutOfMem()
|
||||||
|
|
||||||
else:
|
else:
|
||||||
|
{.warning: "Generic code for allocating pages is used".}
|
||||||
# generic implementation relying on malloc:
|
# generic implementation relying on malloc:
|
||||||
proc malloc(size: int): pointer {.nodecl, importc.}
|
proc malloc(size: int): pointer {.nodecl, importc.}
|
||||||
|
|
||||||
|
|
@ -155,6 +156,124 @@ else:
|
||||||
result = malloc(size)
|
result = malloc(size)
|
||||||
if result == nil: raiseOutOfMem()
|
if result == nil: raiseOutOfMem()
|
||||||
|
|
||||||
|
# ---------------------------------------------------------------------------
|
||||||
|
# small fixed size allocator:
|
||||||
|
|
||||||
|
# Design: We manage pages. A page is of constant size, but not necessarily
|
||||||
|
# the OS's page size. Pages are managed in a hash table taking advantage of
|
||||||
|
# the fact that the OS is likely to give us pages with contingous numbers.
|
||||||
|
# A page contains either small fixed size objects of the same size or
|
||||||
|
# variable length objects. An object's size is always aligned at 16 byte
|
||||||
|
# boundry. Huge objects are dealt with the TLSF algorithm.
|
||||||
|
# The design supports iterating over any object in a fast way.
|
||||||
|
|
||||||
|
# A bitset contains any page that starts an allocated page. The page may be
|
||||||
|
# empty however. This bitset can be used to quickly determine if a given
|
||||||
|
# page belongs to the GC heap. The design of the memory allocator makes it
|
||||||
|
# simple to return unused pages back to the OS.
|
||||||
|
|
||||||
|
|
||||||
|
# Small bocks
|
||||||
|
# -----------
|
||||||
|
#
|
||||||
|
# If we use a list in the free object's space. Allocation and deallocation are
|
||||||
|
# O(1). Since any object is of the same size, iteration is quite efficient too.
|
||||||
|
# However, pointer detection is easy too: Just check if the type-field is nil.
|
||||||
|
# Deallocation sets it to nil.
|
||||||
|
# Algorithm:
|
||||||
|
|
||||||
|
# i = 0
|
||||||
|
# f = b.f # first free address
|
||||||
|
# while i < max:
|
||||||
|
# if a[i] == f: # not a valid block
|
||||||
|
# f = f.next # next free address
|
||||||
|
# else:
|
||||||
|
# a[i] is a valid object of size s
|
||||||
|
# inc(i)
|
||||||
|
|
||||||
|
# The zero count table is an array. Since we know that the RC is zero, we can
|
||||||
|
# use the bits for an index into this array. Thus multiple ZCT tables are not
|
||||||
|
# difficult to support and insertion and removal is O(1). We use negative
|
||||||
|
# indexes for this. This makes it even fast enough (and necessary!) to do a ZCT
|
||||||
|
# removal if the RC is incremented.
|
||||||
|
#
|
||||||
|
|
||||||
|
# Huge blocks
|
||||||
|
# -----------
|
||||||
|
#
|
||||||
|
# Huge blocks are always rounded up to a multiple of the page size. These are
|
||||||
|
# called *strides*. We also need to keep an index structure
|
||||||
|
# of (stridesize, pagelist).
|
||||||
|
#
|
||||||
|
|
||||||
|
const
|
||||||
|
MemAlign = 8
|
||||||
|
PageShift = if sizeof(int) == 4: 12 else: 13
|
||||||
|
PageSize = 1 shl PageShift
|
||||||
|
type
|
||||||
|
TFreeList {.final.} = object
|
||||||
|
next, prev: ptr TFreeList
|
||||||
|
|
||||||
|
TPageDesc {.final.} = object # the start of a stride always starts with this!
|
||||||
|
size: int # lowest bit is set, if it is a huge block
|
||||||
|
free: ptr TFreeList # only used if it manages multiple cells
|
||||||
|
snext, sprev: ptr TPageDesc # next and prev pagedescs with the same size
|
||||||
|
|
||||||
|
TCellArray {.final.} = object
|
||||||
|
i: int # length
|
||||||
|
d: ptr array [0..1000_000, TCell]
|
||||||
|
|
||||||
|
TPageManager = table[page, ptr TPageDesc]
|
||||||
|
|
||||||
|
TGcHeap {.final.} = object
|
||||||
|
# structure that manages the garbage collected heap
|
||||||
|
zct: TCellArray
|
||||||
|
stackCells: TCellArray
|
||||||
|
smallBlocks: array [PageSize div MemAlign, ptr TPageDesc]
|
||||||
|
pages: TPageManager
|
||||||
|
usedPages: TPageList
|
||||||
|
freePages: TPageList
|
||||||
|
|
||||||
|
# small blocks:
|
||||||
|
proc allocSmall(var h: TGcHeap, size: int): pointer =
|
||||||
|
var s = align(size)
|
||||||
|
var p = h.smallBlocks[s]
|
||||||
|
if p == nil or p.free == nil:
|
||||||
|
p = newSmallBlock(s, p)
|
||||||
|
h.smallBlocks[s] = p
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
proc decRef(cell: PCell) {.inline.} =
|
||||||
|
assert(cell in ct.AT)
|
||||||
|
assert(cell.refcount > 0) # this should be the case!
|
||||||
|
assert(seqCheck(cell))
|
||||||
|
dec(cell.refcount)
|
||||||
|
if cell.refcount == 0:
|
||||||
|
# add to zero count table:
|
||||||
|
zct.d[zct.i] = cell
|
||||||
|
cell.recfcount = -zct.i
|
||||||
|
inc(zct.i)
|
||||||
|
|
||||||
|
proc incRef(cell: PCell) {.inline.} =
|
||||||
|
assert(seqCheck(cell))
|
||||||
|
if cell.refcount < 0:
|
||||||
|
# remove from zero count table:
|
||||||
|
zct.d[-cell.refcount] = zct.d[zct.i-1]
|
||||||
|
dec(zct.i)
|
||||||
|
cell.refcount = 1
|
||||||
|
else:
|
||||||
|
inc(cell.refcount)
|
||||||
|
|
||||||
|
proc asgnRef(dest: ppointer, src: pointer) =
|
||||||
|
# the code generator calls this proc!
|
||||||
|
assert(not isOnStack(dest))
|
||||||
|
# BUGFIX: first incRef then decRef!
|
||||||
|
if src != nil: incRef(usrToCell(src))
|
||||||
|
if dest^ != nil: decRef(usrToCell(dest^))
|
||||||
|
dest^ = src
|
||||||
|
|
||||||
|
|
||||||
# ----------------------------------------------------------------------------
|
# ----------------------------------------------------------------------------
|
||||||
# helpers
|
# helpers
|
||||||
|
|
||||||
|
|
@ -261,7 +380,7 @@ proc extractBlock(b: Pbhdr, t: var TLSF, fl, sl: int) {.inline.} =
|
||||||
proc insertBlock(b: Pbhdr, t: var TLSF, fl, sl: int) {.inline.} =
|
proc insertBlock(b: Pbhdr, t: var TLSF, fl, sl: int) {.inline.} =
|
||||||
b.freePtr.prev = nil
|
b.freePtr.prev = nil
|
||||||
b.freePtr.next = t.matrix[fl][sl]
|
b.freePtr.next = t.matrix[fl][sl]
|
||||||
if t.matrix[fl][sl] != 0:
|
if t.matrix[fl][sl] != nil:
|
||||||
t.matrix[fl][sl].freePtr.prev = b
|
t.matrix[fl][sl].freePtr.prev = b
|
||||||
t.matrix[fl][sl] = b
|
t.matrix[fl][sl] = b
|
||||||
set_bit(sl, t.slBitmap[fl])
|
set_bit(sl, t.slBitmap[fl])
|
||||||
|
|
@ -295,9 +414,6 @@ proc processArea(area: pointer, size: int): Pbhdr =
|
||||||
# ----------------------------------------------------------------------------
|
# ----------------------------------------------------------------------------
|
||||||
# Begin of the allocator code
|
# Begin of the allocator code
|
||||||
|
|
||||||
var
|
|
||||||
mp: pointer # default memory pool.
|
|
||||||
|
|
||||||
proc initMemoryPool(memPoolSize: int, memPool: pointer): int =
|
proc initMemoryPool(memPoolSize: int, memPool: pointer): int =
|
||||||
var
|
var
|
||||||
t: PLSF
|
t: PLSF
|
||||||
|
|
@ -307,16 +423,14 @@ proc initMemoryPool(memPoolSize: int, memPool: pointer): int =
|
||||||
writeToStdErr("initMemoryPool(): memory_pool invalid\n")
|
writeToStdErr("initMemoryPool(): memory_pool invalid\n")
|
||||||
return -1
|
return -1
|
||||||
|
|
||||||
if (memPool and ptrMask) != 0:
|
if (cast[TAddress](memPool) and ptrMask) != 0:
|
||||||
writeToStdErr("initMemoryPool(): memPool must be aligned to a word\n")
|
writeToStdErr("initMemoryPool(): memPool must be aligned to a word\n")
|
||||||
return -1
|
return -1
|
||||||
t = cast[PLSF](memPool)
|
t = cast[PLSF](memPool)
|
||||||
# Check if already initialised
|
# Check if already initialised
|
||||||
if t.signature == tlsfSignature:
|
if t.signature == tlsfSignature:
|
||||||
mp = memPool
|
b = getNextBlock(memPool, roundupSize(sizeof(TLSF)))
|
||||||
b = getNextBlock(mp, roundupSize(sizeof(TLSF)))
|
|
||||||
return b.size and blockSize
|
return b.size and blockSize
|
||||||
mp = memPool
|
|
||||||
zeroMem(memPool, sizeof(TLSF))
|
zeroMem(memPool, sizeof(TLSF))
|
||||||
|
|
||||||
t.signature = tlsfSignature
|
t.signature = tlsfSignature
|
||||||
|
|
@ -456,7 +570,7 @@ proc freeEx(p: pointer, t: var TLSF) =
|
||||||
b.freePtr.prev = nil
|
b.freePtr.prev = nil
|
||||||
b.freePtr.next = nil
|
b.freePtr.next = nil
|
||||||
tmpB = getNextBlock(getBuffer(b), b.size and blockSize)
|
tmpB = getNextBlock(getBuffer(b), b.size and blockSize)
|
||||||
if tmpB.size and freeBlock != 0:
|
if (tmpB.size and freeBlock) != 0:
|
||||||
mappingInsert(tmpB.size and blockSize, fl, sl)
|
mappingInsert(tmpB.size and blockSize, fl, sl)
|
||||||
extractBlock(tmpB, t, fl, sl)
|
extractBlock(tmpB, t, fl, sl)
|
||||||
inc(b.size, (tmpB.size and blockSize) + bhdrOverhead)
|
inc(b.size, (tmpB.size and blockSize) + bhdrOverhead)
|
||||||
|
|
@ -549,51 +663,30 @@ proc ansiCrealloc(p: pointer, newSize: int, t: var TLSF): pointer =
|
||||||
else:
|
else:
|
||||||
result = reallocEx(p, newSize, t)
|
result = reallocEx(p, newSize, t)
|
||||||
|
|
||||||
|
proc InitTLSF(t: var TLSF) =
|
||||||
|
var areaSize = sizeof(TLSF) + BHDR_OVERHEAD * 8 # Just a safety constant
|
||||||
|
areaSize = max(areaSize, DEFAULT_areaSize)
|
||||||
|
var area = getNewArea(areaSize)
|
||||||
|
|
||||||
void *tlsf_malloc(size_t size)
|
|
||||||
{
|
|
||||||
void *ret
|
|
||||||
|
|
||||||
#if USE_MMAP || USE_SBRK
|
|
||||||
if (!mp) {
|
|
||||||
size_t areaSize
|
|
||||||
void *area
|
|
||||||
|
|
||||||
areaSize = sizeof(tlsf_t) + BHDR_OVERHEAD * 8 # Just a safety constant
|
|
||||||
areaSize = (areaSize > DEFAULT_areaSize) ? areaSize : DEFAULT_areaSize
|
|
||||||
area = get_new_area(&areaSize)
|
|
||||||
if (area == ((void *) ~0))
|
|
||||||
return NULL # Not enough system memory
|
|
||||||
initMemoryPool(areaSize, area)
|
initMemoryPool(areaSize, area)
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
TLSF_ACQUIRE_LOCK(&((tlsf_t *)mp)->lock)
|
var
|
||||||
|
t: PLSF
|
||||||
|
b, ib: Pbhdr
|
||||||
|
|
||||||
ret = malloc_ex(size, mp)
|
t = cast[PLSF](memPool)
|
||||||
|
|
||||||
TLSF_RELEASE_LOCK(&((tlsf_t *)mp)->lock)
|
zeroMem(area, areaSize)
|
||||||
|
|
||||||
return ret
|
t.signature = tlsfSignature
|
||||||
}
|
var ib = processArea(getNextBlock(memPool, roundupSize(sizeof(TLSF))),
|
||||||
|
rounddownSize(memPoolSize - sizeof(TLSF)))
|
||||||
|
var b = getNextBlock(getBuffer(ib), ib.size and blockSize)
|
||||||
|
freeEx(getBuffer(b), t)
|
||||||
|
t.areaHead = cast[PAreaInfo](getBuffer(ib))
|
||||||
|
|
||||||
void tlsf_free(void *p)
|
t.used_size = memPoolSize - (b.size and blockSize)
|
||||||
{
|
t.max_size = t.used_size
|
||||||
TLSF_ACQUIRE_LOCK(&((tlsf_t *)mp)->lock)
|
|
||||||
free_ex(p, mp)
|
|
||||||
TLSF_RELEASE_LOCK(&((tlsf_t *)mp)->lock)
|
|
||||||
}
|
|
||||||
|
|
||||||
void *tlsf_realloc(void *p, size_t size)
|
# XXX
|
||||||
{
|
|
||||||
void *ret
|
|
||||||
#if USE_MMAP || USE_SBRK
|
|
||||||
if (!mp) {
|
|
||||||
return tlsf_malloc(size)
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
TLSF_ACQUIRE_LOCK(&((tlsf_t *)mp)->lock)
|
|
||||||
ret = realloc_ex(p, size, mp)
|
|
||||||
TLSF_RELEASE_LOCK(&((tlsf_t *)mp)->lock)
|
|
||||||
return ret
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
|
|
||||||
Nimrod's Runtime Library
|
Nimrod's Runtime Library
|
||||||
(c) Copyright 2006 Andreas Rumpf
|
(c) Copyright 2008 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.
|
||||||
|
|
@ -11,7 +11,8 @@
|
||||||
#define NIMBASE_H
|
#define NIMBASE_H
|
||||||
|
|
||||||
/* calling convention mess ----------------------------------------------- */
|
/* calling convention mess ----------------------------------------------- */
|
||||||
#if defined(__GNUC__) || defined(__LCC__) || defined(__POCC__)
|
#if defined(__GNUC__) || defined(__LCC__) || defined(__POCC__) \
|
||||||
|
|| defined(__TINYC__)
|
||||||
/* these should support C99's inline */
|
/* these should support C99's inline */
|
||||||
/* the test for __POCC__ has to come before the test for _MSC_VER,
|
/* the test for __POCC__ has to come before the test for _MSC_VER,
|
||||||
because PellesC defines _MSC_VER too. This is brain-dead. */
|
because PellesC defines _MSC_VER too. This is brain-dead. */
|
||||||
|
|
@ -30,10 +31,18 @@
|
||||||
# define N_INLINE(rettype, name) rettype __inline name
|
# define N_INLINE(rettype, name) rettype __inline name
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(_MSC_VER)
|
#if defined(__POCC__) || defined(_MSC_VER)
|
||||||
# define HAVE_LRINT 1
|
# define HAVE_LRINT 1
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(__POCC__)
|
||||||
|
# define NIM_CONST /* PCC is really picky with const modifiers */
|
||||||
|
#elif defined(__cplusplus)
|
||||||
|
# define NIM_CONST /* C++ is picky with const modifiers */
|
||||||
|
#else
|
||||||
|
# define NIM_CONST const
|
||||||
|
#endif
|
||||||
|
|
||||||
/* --------------- how int64 constants should be declared: ----------- */
|
/* --------------- how int64 constants should be declared: ----------- */
|
||||||
#if defined(__GNUC__) || defined(__LCC__) || \
|
#if defined(__GNUC__) || defined(__LCC__) || \
|
||||||
defined(__POCC__) || defined(__DMC__)
|
defined(__POCC__) || defined(__DMC__)
|
||||||
|
|
@ -136,8 +145,7 @@
|
||||||
** long int lrint (double x);
|
** long int lrint (double x);
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#if defined(__LCC__) || defined(__POCC__) \
|
#if defined(__LCC__) || (defined(__GNUC__) && defined(WIN32))
|
||||||
|| (defined(__GNUC__) && defined(WIN32))
|
|
||||||
/* Linux' GCC does not seem to have these. Why? */
|
/* Linux' GCC does not seem to have these. Why? */
|
||||||
# define HAVE_LRINT
|
# define HAVE_LRINT
|
||||||
# define HAVE_LRINTF
|
# define HAVE_LRINTF
|
||||||
|
|
@ -159,7 +167,7 @@
|
||||||
# include <math.h>
|
# include <math.h>
|
||||||
|
|
||||||
#elif (defined(WIN32) || defined(_WIN32) || defined(__WIN32__)) \
|
#elif (defined(WIN32) || defined(_WIN32) || defined(__WIN32__)) \
|
||||||
&& !defined(__BORLANDC__)
|
&& !defined(__BORLANDC__) && !defined(__POCC__)
|
||||||
|
|
||||||
# include <math.h>
|
# include <math.h>
|
||||||
|
|
||||||
|
|
@ -206,6 +214,17 @@ static N_INLINE(long int, lrintf)(float flt) {
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <setjmp.h>
|
#include <setjmp.h>
|
||||||
|
|
||||||
|
#ifndef NAN
|
||||||
|
static unsigned long nimNaN[2]={0xffffffff, 0x7fffffff};
|
||||||
|
# define NAN (*(double*) nimNaN)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
#ifndef INF
|
||||||
|
static unsigned long nimInf[2]={0xffffffff, 0x7fffffff};
|
||||||
|
# define INF (*(double*) nimInf)
|
||||||
|
#endif */
|
||||||
|
|
||||||
/* compiler symbols:
|
/* compiler symbols:
|
||||||
__BORLANDC__
|
__BORLANDC__
|
||||||
_MSC_VER
|
_MSC_VER
|
||||||
|
|
@ -214,6 +233,7 @@ __LCC__
|
||||||
__GNUC__
|
__GNUC__
|
||||||
__DMC__
|
__DMC__
|
||||||
__POCC__
|
__POCC__
|
||||||
|
__TINYC__
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* C99 compiler? */
|
/* C99 compiler? */
|
||||||
|
|
@ -254,46 +274,37 @@ __POCC__
|
||||||
|
|
||||||
#if defined(HAVE_STDINT_H)
|
#if defined(HAVE_STDINT_H)
|
||||||
# include <stdint.h>
|
# include <stdint.h>
|
||||||
typedef int8_t NS8;
|
typedef int8_t NI8;
|
||||||
typedef int16_t NS16;
|
typedef int16_t NI16;
|
||||||
typedef int32_t NS32;
|
typedef int32_t NI32;
|
||||||
typedef int64_t NS64;
|
typedef int64_t NI64;
|
||||||
typedef uint64_t NU64;
|
typedef uint64_t NU64;
|
||||||
typedef uint8_t NU8;
|
typedef uint8_t NU8;
|
||||||
typedef uint16_t NU16;
|
typedef uint16_t NU16;
|
||||||
typedef uint32_t NU32;
|
typedef uint32_t NU32;
|
||||||
#elif defined(__BORLANDC__) || defined(__DMC__) \
|
#elif defined(__BORLANDC__) || defined(__DMC__) \
|
||||||
|| defined(__WATCOMC__) || defined(_MSC_VER)
|
|| defined(__WATCOMC__) || defined(_MSC_VER)
|
||||||
typedef signed char NS8;
|
typedef signed char NI8;
|
||||||
typedef signed short int NS16;
|
typedef signed short int NI16;
|
||||||
typedef signed int NS32;
|
typedef signed int NI32;
|
||||||
/* XXX: Float128? */
|
/* XXX: Float128? */
|
||||||
typedef unsigned char NU8;
|
typedef unsigned char NU8;
|
||||||
typedef unsigned short int NU16;
|
typedef unsigned short int NU16;
|
||||||
typedef unsigned __int64 NU64;
|
typedef unsigned __int64 NU64;
|
||||||
typedef __int64 NS64;
|
typedef __int64 NI64;
|
||||||
typedef unsigned int NU32;
|
typedef unsigned int NU32;
|
||||||
#else
|
#else
|
||||||
typedef signed char NS8;
|
typedef signed char NI8;
|
||||||
typedef signed short int NS16;
|
typedef signed short int NI16;
|
||||||
typedef signed int NS32;
|
typedef signed int NI32;
|
||||||
/* XXX: Float128? */
|
/* XXX: Float128? */
|
||||||
typedef unsigned char NU8;
|
typedef unsigned char NU8;
|
||||||
typedef unsigned short int NU16;
|
typedef unsigned short int NU16;
|
||||||
typedef unsigned long long int NU64;
|
typedef unsigned long long int NU64;
|
||||||
typedef long long int NS64;
|
typedef long long int NI64;
|
||||||
typedef unsigned int NU32;
|
typedef unsigned int NU32;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(_MSC_VER) && (defined(AMD64) || defined(_M_AMD64))
|
|
||||||
/* Microsoft C is brain-dead in this case; long is still not an int64 */
|
|
||||||
typedef unsigned long long int NU;
|
|
||||||
typedef signed long long int NS;
|
|
||||||
#else
|
|
||||||
typedef unsigned long int NU; /* note: int would be wrong for AMD64 */
|
|
||||||
typedef signed long int NS;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
typedef float NF32;
|
typedef float NF32;
|
||||||
typedef double NF64;
|
typedef double NF64;
|
||||||
typedef double NF;
|
typedef double NF;
|
||||||
|
|
@ -307,13 +318,13 @@ typedef char* NCSTRING;
|
||||||
# define NIM_IMAN 0
|
# define NIM_IMAN 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static N_INLINE(NS32, float64ToInt32)(double val) {
|
static N_INLINE(NI32, float64ToInt32)(double val) {
|
||||||
val = val + 68719476736.0*1.5;
|
val = val + 68719476736.0*1.5;
|
||||||
/* 2^36 * 1.5, (52-_shiftamt=36) uses limited precisicion to floor */
|
/* 2^36 * 1.5, (52-_shiftamt=36) uses limited precisicion to floor */
|
||||||
return ((NS32*)&val)[NIM_IMAN] >> 16; /* 16.16 fixed point representation */
|
return ((NI32*)&val)[NIM_IMAN] >> 16; /* 16.16 fixed point representation */
|
||||||
}
|
}
|
||||||
|
|
||||||
static N_INLINE(NS32, float32ToInt32)(float val) {
|
static N_INLINE(NI32, float32ToInt32)(float val) {
|
||||||
return float64ToInt32((double)val);
|
return float64ToInt32((double)val);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -322,7 +333,7 @@ static N_INLINE(NS32, float32ToInt32)(float val) {
|
||||||
|
|
||||||
#define STRING_LITERAL(name, str, length) \
|
#define STRING_LITERAL(name, str, length) \
|
||||||
static const struct { \
|
static const struct { \
|
||||||
NS len, space; \
|
NI len, space; \
|
||||||
NIM_CHAR data[length + 1]; \
|
NIM_CHAR data[length + 1]; \
|
||||||
} name = {length, length, str}
|
} name = {length, length, str}
|
||||||
|
|
||||||
|
|
@ -357,7 +368,7 @@ typedef struct TStringDesc* string;
|
||||||
/*
|
/*
|
||||||
typedef struct TSafePoint TSafePoint;
|
typedef struct TSafePoint TSafePoint;
|
||||||
struct TSafePoint {
|
struct TSafePoint {
|
||||||
NS exc;
|
NI exc;
|
||||||
NCSTRING excname;
|
NCSTRING excname;
|
||||||
NCSTRING msg;
|
NCSTRING msg;
|
||||||
TSafePoint* prev;
|
TSafePoint* prev;
|
||||||
|
|
@ -368,19 +379,19 @@ typedef struct TFrame TFrame;
|
||||||
struct TFrame {
|
struct TFrame {
|
||||||
TFrame* prev;
|
TFrame* prev;
|
||||||
NCSTRING procname;
|
NCSTRING procname;
|
||||||
NS line;
|
NI line;
|
||||||
NCSTRING filename;
|
NCSTRING filename;
|
||||||
NS len;
|
NI len;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern TFrame* volatile framePtr;
|
extern TFrame* framePtr;
|
||||||
/*extern TSafePoint* volatile excHandler; */
|
/*extern TSafePoint* excHandler; */
|
||||||
|
|
||||||
#if defined(__cplusplus)
|
#if defined(__cplusplus)
|
||||||
struct NimException {
|
struct NimException {
|
||||||
TSafePoint sp;
|
TSafePoint sp;
|
||||||
|
|
||||||
NimException(NS aExc, NCSTRING aExcname, NCSTRING aMsg) {
|
NimException(NI aExc, NCSTRING aExcname, NCSTRING aMsg) {
|
||||||
sp.exc = aExc; sp.excname = aExcname; sp.msg = aMsg;
|
sp.exc = aExc; sp.excname = aExcname; sp.msg = aMsg;
|
||||||
sp.prev = excHandler;
|
sp.prev = excHandler;
|
||||||
excHandler = &sp;
|
excHandler = &sp;
|
||||||
|
|
@ -389,13 +400,13 @@ struct NimException {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
typedef struct TStringDesc {
|
typedef struct TStringDesc {
|
||||||
NS len;
|
NI len;
|
||||||
NS space;
|
NI space;
|
||||||
NIM_CHAR data[1]; /* SEQ_DECL_SIZE]; */
|
NIM_CHAR data[1]; /* SEQ_DECL_SIZE]; */
|
||||||
} TStringDesc;
|
} TStringDesc;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
NS len, space;
|
NI len, space;
|
||||||
} TGenericSeq;
|
} TGenericSeq;
|
||||||
|
|
||||||
typedef TGenericSeq* PGenericSeq;
|
typedef TGenericSeq* PGenericSeq;
|
||||||
|
|
|
||||||
|
|
@ -1,39 +0,0 @@
|
||||||
#
|
|
||||||
#
|
|
||||||
# Nimrod's Runtime Library
|
|
||||||
# (c) Copyright 2006 Andreas Rumpf
|
|
||||||
#
|
|
||||||
# See the file "copying.txt", included in this
|
|
||||||
# distribution, for details about the copyright.
|
|
||||||
#
|
|
||||||
|
|
||||||
|
|
||||||
## This module provides a command line parser.
|
|
||||||
## It supports one iterator over all command line options.
|
|
||||||
|
|
||||||
#interface
|
|
||||||
|
|
||||||
{.push debugger: off.}
|
|
||||||
|
|
||||||
import
|
|
||||||
os
|
|
||||||
|
|
||||||
proc findSep(s: string): int {.nostatic.} =
|
|
||||||
for i in 0 .. high(s)-1:
|
|
||||||
if s[i] in {'=', ':'}: return i
|
|
||||||
return high(s)+1
|
|
||||||
|
|
||||||
iterator getopt*(): tuple[string, string] =
|
|
||||||
# returns a (cmd, arg) tuple.
|
|
||||||
for k in 1 .. ParamCount():
|
|
||||||
var param = paramStr(k)
|
|
||||||
if param[0] == '-':
|
|
||||||
var j = findSep(param)
|
|
||||||
cmd = copy(param, 0, j-1)
|
|
||||||
arg = copy(param, j+1)
|
|
||||||
else:
|
|
||||||
cmd = ""
|
|
||||||
arg = param
|
|
||||||
yield cmd, arg
|
|
||||||
|
|
||||||
{.pop.}
|
|
||||||
76
lib/os.nim
76
lib/os.nim
|
|
@ -1,7 +1,7 @@
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
# Nimrod's Runtime Library
|
# Nimrod's Runtime Library
|
||||||
# (c) Copyright 2006 Andreas Rumpf
|
# (c) Copyright 2008 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.
|
||||||
|
|
@ -10,7 +10,9 @@
|
||||||
## Basic operating system facilities like retrieving environment variables,
|
## Basic operating system facilities like retrieving environment variables,
|
||||||
## reading command line arguments, working with directories, running shell
|
## reading command line arguments, working with directories, running shell
|
||||||
## commands, etc. This module is -- like any other basic library --
|
## commands, etc. This module is -- like any other basic library --
|
||||||
## platform independant.
|
## platform independant. However, the ECMAScript target is not supported,
|
||||||
|
## as there is no way to perform these operations in ECMAScript portably
|
||||||
|
## or at all.
|
||||||
|
|
||||||
{.push debugger:off.}
|
{.push debugger:off.}
|
||||||
|
|
||||||
|
|
@ -371,8 +373,11 @@ proc UnixToNativePath(path: string): string =
|
||||||
|
|
||||||
# interface to C library:
|
# interface to C library:
|
||||||
|
|
||||||
|
const
|
||||||
|
cunder = if defined(pcc): "_" else: ""
|
||||||
|
|
||||||
type
|
type
|
||||||
TStat {.importc: "struct stat".} = record
|
TStat {.importc: "struct " & cunder & "stat", final.} = object
|
||||||
st_dev: int16
|
st_dev: int16
|
||||||
st_ino: int16
|
st_ino: int16
|
||||||
st_mode: int16
|
st_mode: int16
|
||||||
|
|
@ -397,7 +402,8 @@ else:
|
||||||
{.error: "os library not ported to your OS. Please help!".}
|
{.error: "os library not ported to your OS. Please help!".}
|
||||||
|
|
||||||
|
|
||||||
proc chdir(path: CString): cint {.importc: "chdir", header: dirHeader.}
|
proc chdir(path: CString): cint {.
|
||||||
|
importc: cunder & "chdir", header: dirHeader.}
|
||||||
|
|
||||||
when defined(unix):
|
when defined(unix):
|
||||||
proc mkdir(dir: CString, theAccess: cint): cint {.
|
proc mkdir(dir: CString, theAccess: cint): cint {.
|
||||||
|
|
@ -412,7 +418,7 @@ elif defined(windows):
|
||||||
proc fullpath(buffer, file: CString, size: int): CString {.
|
proc fullpath(buffer, file: CString, size: int): CString {.
|
||||||
importc: "_fullpath", header: "<stdlib.h>".}
|
importc: "_fullpath", header: "<stdlib.h>".}
|
||||||
proc getcwd(buf: CString, buflen: cint): CString {.
|
proc getcwd(buf: CString, buflen: cint): CString {.
|
||||||
importc: "getcwd", header: "<direct.h>".}
|
importc: cunder & "getcwd", header: "<direct.h>".}
|
||||||
|
|
||||||
proc CreateDirectory(pathName: cstring, security: Pointer): cint {.
|
proc CreateDirectory(pathName: cstring, security: Pointer): cint {.
|
||||||
importc: "CreateDirectory", header: "<windows.h>".}
|
importc: "CreateDirectory", header: "<windows.h>".}
|
||||||
|
|
@ -421,7 +427,8 @@ else:
|
||||||
{.error: "os library not ported to your OS. Please help!".}
|
{.error: "os library not ported to your OS. Please help!".}
|
||||||
|
|
||||||
|
|
||||||
proc rmdir(dir: CString): cint {.importc: "rmdir", header: "<time.h>".}
|
proc rmdir(dir: CString): cint {.
|
||||||
|
importc: cunder & "rmdir", header: "<time.h>".}
|
||||||
# rmdir is of course in ``dirHeader``, but we check here to include
|
# rmdir is of course in ``dirHeader``, but we check here to include
|
||||||
# time.h which is needed for stat(). stat() needs time.h and
|
# time.h which is needed for stat(). stat() needs time.h and
|
||||||
# sys/stat.h; we workaround a C library issue here.
|
# sys/stat.h; we workaround a C library issue here.
|
||||||
|
|
@ -432,17 +439,7 @@ proc free(c: cstring) {.importc: "free", nodecl.}
|
||||||
proc strlen(str: CString): int {.importc: "strlen", nodecl.}
|
proc strlen(str: CString): int {.importc: "strlen", nodecl.}
|
||||||
|
|
||||||
proc stat(f: CString, res: var TStat): cint {.
|
proc stat(f: CString, res: var TStat): cint {.
|
||||||
importc: "stat", header: "<sys/stat.h>".}
|
importc: cunder & "stat", header: "<sys/stat.h>".}
|
||||||
|
|
||||||
proc sameFile*(path1, path2: string): bool =
|
|
||||||
## Returns True if both pathname arguments refer to the same file or
|
|
||||||
## directory (as indicated by device number and i-node number).
|
|
||||||
## Raises an exception if an os.stat() call on either pathname fails.
|
|
||||||
var
|
|
||||||
a, b: TStat
|
|
||||||
if stat(path1, a) < 0 or stat(path2, b) < 0:
|
|
||||||
raise newException(EOS, "stat() call failed")
|
|
||||||
return int(a.st_dev) == b.st_dev and int(a.st_ino) == b.st_ino
|
|
||||||
|
|
||||||
when defined(windows):
|
when defined(windows):
|
||||||
proc getModuleFilename(handle: int32, buf: CString, size: int32): int32 {.
|
proc getModuleFilename(handle: int32, buf: CString, size: int32): int32 {.
|
||||||
|
|
@ -473,6 +470,13 @@ when defined(linux) or defined(solaris) or defined(bsd):
|
||||||
|
|
||||||
when defined(solaris) or defined(bsd):
|
when defined(solaris) or defined(bsd):
|
||||||
proc getpid(): int {.importc, header: "<unistd.h>", cdecl.}
|
proc getpid(): int {.importc, header: "<unistd.h>", cdecl.}
|
||||||
|
elif defined(macosx):
|
||||||
|
# a really hacky solution: since we like to include 2 headers we have to
|
||||||
|
# define two procs which in reality are the same
|
||||||
|
proc getExecPath1(c: cstring, size: var int32) {.
|
||||||
|
importc: "_NSGetExecutablePath", header: "<sys/param.h>".}
|
||||||
|
proc getExecPath2(c: cstring, size: var int32): bool {.
|
||||||
|
importc: "_NSGetExecutablePath", header: "<mach-o/dyld.h>".}
|
||||||
|
|
||||||
proc getApplicationFilename(): string =
|
proc getApplicationFilename(): string =
|
||||||
# Linux: /proc/<pid>/exe
|
# Linux: /proc/<pid>/exe
|
||||||
|
|
@ -491,6 +495,12 @@ proc getApplicationFilename(): string =
|
||||||
result = getApplAux("/proc/" & $getpid() & "/path/a.out")
|
result = getApplAux("/proc/" & $getpid() & "/path/a.out")
|
||||||
elif defined(bsd):
|
elif defined(bsd):
|
||||||
result = getApplAux("/proc/" & $getpid() & "file")
|
result = getApplAux("/proc/" & $getpid() & "file")
|
||||||
|
elif defined(macosx):
|
||||||
|
var size: int32
|
||||||
|
getExecPath1(nil, size)
|
||||||
|
result = newString(int(size))
|
||||||
|
if getExecPath2(result, size):
|
||||||
|
result = "" # error!
|
||||||
else:
|
else:
|
||||||
# little heuristic that may work on other POSIX-like systems:
|
# little heuristic that may work on other POSIX-like systems:
|
||||||
result = getEnv("_")
|
result = getEnv("_")
|
||||||
|
|
@ -612,7 +622,7 @@ when defined(wcc):
|
||||||
proc cputenv(env: CString): cint {.importc: "putenv", header: "<process.h>".}
|
proc cputenv(env: CString): cint {.importc: "putenv", header: "<process.h>".}
|
||||||
|
|
||||||
else: # is in <stdlib.h>
|
else: # is in <stdlib.h>
|
||||||
proc cputenv(env: CString): cint {.importc: "putenv", noDecl.}
|
proc cputenv(env: CString): cint {.importc: cunder & "putenv", noDecl.}
|
||||||
|
|
||||||
proc cgetenv(env: CString): CString {.importc: "getenv", noDecl.}
|
proc cgetenv(env: CString): CString {.importc: "getenv", noDecl.}
|
||||||
|
|
||||||
|
|
@ -621,7 +631,7 @@ proc cgetenv(env: CString): CString {.importc: "getenv", noDecl.}
|
||||||
#int _findclose(long);
|
#int _findclose(long);
|
||||||
when defined(windows):
|
when defined(windows):
|
||||||
type
|
type
|
||||||
TFindData {.importc: "struct _finddata_t".} = record
|
TFindData {.importc: "struct _finddata_t", final.} = object
|
||||||
attrib {.importc: "attrib".}: cint
|
attrib {.importc: "attrib".}: cint
|
||||||
time_create {.importc: "time_create".}: cint
|
time_create {.importc: "time_create".}: cint
|
||||||
time_access {.importc: "time_access".}: cint
|
time_access {.importc: "time_access".}: cint
|
||||||
|
|
@ -636,7 +646,7 @@ when defined(windows):
|
||||||
proc findclose(handle: cint) {.importc: "_findclose", header: "<io.h>".}
|
proc findclose(handle: cint) {.importc: "_findclose", header: "<io.h>".}
|
||||||
else:
|
else:
|
||||||
type
|
type
|
||||||
TFindData {.importc: "glob_t".} = record
|
TFindData {.importc: "glob_t", final.} = object
|
||||||
gl_pathc: int # count of paths matched by pattern
|
gl_pathc: int # count of paths matched by pattern
|
||||||
gl_pathv: ptr array[0..1000_000, CString] # list of matched path names
|
gl_pathv: ptr array[0..1000_000, CString] # list of matched path names
|
||||||
gl_offs: int # slots to reserve at beginning of gl_pathv
|
gl_offs: int # slots to reserve at beginning of gl_pathv
|
||||||
|
|
@ -649,6 +659,30 @@ else:
|
||||||
proc globfree(pglob: PFindData) {.
|
proc globfree(pglob: PFindData) {.
|
||||||
importc: "globfree", header: "<glob.h>".}
|
importc: "globfree", header: "<glob.h>".}
|
||||||
|
|
||||||
|
proc sameFile*(path1, path2: string): bool =
|
||||||
|
## Returns True if both pathname arguments refer to the same file or
|
||||||
|
## directory (as indicated by device number and i-node number).
|
||||||
|
## Raises an exception if an os.stat() call on either pathname fails.
|
||||||
|
when defined(Windows):
|
||||||
|
var
|
||||||
|
a, b: TFindData
|
||||||
|
var resA = findfirst(path1, addr(a))
|
||||||
|
var resB = findfirst(path2, addr(b))
|
||||||
|
if resA != -1 and resB != -1:
|
||||||
|
result = $a.name == $b.name
|
||||||
|
else:
|
||||||
|
# work around some ``findfirst`` bugs
|
||||||
|
result = cmpPaths(path1, path2) == 0
|
||||||
|
if resA != -1: findclose(resA)
|
||||||
|
if resB != -1: findclose(resB)
|
||||||
|
else:
|
||||||
|
var
|
||||||
|
a, b: TStat
|
||||||
|
if stat(path1, a) < 0 or stat(path2, b) < 0:
|
||||||
|
result = cmpPaths(path1, path2) == 0 # be consistent with Windows
|
||||||
|
else:
|
||||||
|
result = int(a.st_dev) == b.st_dev and int(a.st_ino) == b.st_ino
|
||||||
|
|
||||||
proc cremove(filename: CString): cint {.importc: "remove", noDecl.}
|
proc cremove(filename: CString): cint {.importc: "remove", noDecl.}
|
||||||
proc crename(oldname, newname: CString): cint {.importc: "rename", noDecl.}
|
proc crename(oldname, newname: CString): cint {.importc: "rename", noDecl.}
|
||||||
|
|
||||||
|
|
@ -787,7 +821,7 @@ proc existsEnv(key: string): bool =
|
||||||
if cgetenv(key) != nil: return true
|
if cgetenv(key) != nil: return true
|
||||||
else: return findEnvVar(key) >= 0
|
else: return findEnvVar(key) >= 0
|
||||||
|
|
||||||
iterator iterOverEnvironment*(): tuple[string, string] =
|
iterator iterOverEnvironment*(): tuple[key, value: string] =
|
||||||
## Iterate over all environments varialbes. In the first component of the
|
## Iterate over all environments varialbes. In the first component of the
|
||||||
## tuple is the name of the current variable stored, in the second its value.
|
## tuple is the name of the current variable stored, in the second its value.
|
||||||
getEnvVarsC()
|
getEnvVarsC()
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@
|
||||||
## This is a raw POSIX interface module. It does not not provide any
|
## This is a raw POSIX interface module. It does not not provide any
|
||||||
## convenience: cstrings are used instead of proper Nimrod strings and
|
## convenience: cstrings are used instead of proper Nimrod strings and
|
||||||
## return codes indicate errors. If you want exceptions
|
## return codes indicate errors. If you want exceptions
|
||||||
## and a proper Nimrod-like interface, use the OS module.
|
## and a proper Nimrod-like interface, use the OS module or write a wrapper.
|
||||||
|
|
||||||
## Coding conventions:
|
## Coding conventions:
|
||||||
## ALL types are named the same as in the POSIX standard except that they start
|
## ALL types are named the same as in the POSIX standard except that they start
|
||||||
|
|
@ -60,7 +60,7 @@ const
|
||||||
STDOUT_FILENO = 1 ## File number of stdout;
|
STDOUT_FILENO = 1 ## File number of stdout;
|
||||||
|
|
||||||
type
|
type
|
||||||
Taiocb* {.importc: "struct aiocb", header: "<aio.h>".} = record
|
Taiocb* {.importc: "struct aiocb", header: "<aio.h>", final.} = object
|
||||||
aio_fildes*: cint ## File descriptor.
|
aio_fildes*: cint ## File descriptor.
|
||||||
aio_offset*: TOff ## File offset.
|
aio_offset*: TOff ## File offset.
|
||||||
aio_buf*: pointer ## Location of buffer.
|
aio_buf*: pointer ## Location of buffer.
|
||||||
|
|
@ -69,14 +69,14 @@ type
|
||||||
aio_sigevent*: TSigEvent ## Signal number and value.
|
aio_sigevent*: TSigEvent ## Signal number and value.
|
||||||
aio_lio_opcode: cint ## Operation to be performed.
|
aio_lio_opcode: cint ## Operation to be performed.
|
||||||
|
|
||||||
TDIR* {.importc: "DIR", header: "<dirent.h>".} = record
|
TDIR* {.importc: "DIR", header: "<dirent.h>", final.} = object
|
||||||
## A type representing a directory stream.
|
## A type representing a directory stream.
|
||||||
|
|
||||||
Tdirent* {.importc: "struct dirent", header: "<dirent.h>".} = record
|
Tdirent* {.importc: "struct dirent", header: "<dirent.h>", final.} = object
|
||||||
d_ino*: TIno ## File serial number.
|
d_ino*: TIno ## File serial number.
|
||||||
d_name*: array [0..255, char] ## Name of entry.
|
d_name*: array [0..255, char] ## Name of entry.
|
||||||
|
|
||||||
Tflock* {.importc: "flock", header: "<fcntl>".} = record
|
Tflock* {.importc: "flock", header: "<fcntl>", final.} = object
|
||||||
l_type*: cshort ## Type of lock; F_RDLCK, F_WRLCK, F_UNLCK.
|
l_type*: cshort ## Type of lock; F_RDLCK, F_WRLCK, F_UNLCK.
|
||||||
l_whence*: cshort ## Flag for starting offset.
|
l_whence*: cshort ## Flag for starting offset.
|
||||||
l_start*: Toff ## Relative offset in bytes.
|
l_start*: Toff ## Relative offset in bytes.
|
||||||
|
|
@ -84,13 +84,13 @@ type
|
||||||
l_pid*: TPid ## Process ID of the process holding the lock;
|
l_pid*: TPid ## Process ID of the process holding the lock;
|
||||||
## returned with F_GETLK.
|
## returned with F_GETLK.
|
||||||
|
|
||||||
Tfenv* {.importc: "fenv_t", header: "<fenv.h>".} =
|
Tfenv* {.importc: "fenv_t", header: "<fenv.h>", final.} =
|
||||||
record ## Represents the entire floating-point environment. The
|
object ## Represents the entire floating-point environment. The
|
||||||
## floating-point environment refers collectively to any
|
## floating-point environment refers collectively to any
|
||||||
## floating-point status flags and control modes supported
|
## floating-point status flags and control modes supported
|
||||||
## by the implementation.
|
## by the implementation.
|
||||||
Tfexcept* {.importc: "fexcept_t", header: "<fenv.h>".} =
|
Tfexcept* {.importc: "fexcept_t", header: "<fenv.h>", final.} =
|
||||||
record ## Represents the floating-point status flags collectively,
|
object ## Represents the floating-point status flags collectively,
|
||||||
## including any status the implementation associates with the
|
## including any status the implementation associates with the
|
||||||
## flags. A floating-point status flag is a system variable
|
## flags. A floating-point status flag is a system variable
|
||||||
## whose value is set (but never cleared) when a floating-point
|
## whose value is set (but never cleared) when a floating-point
|
||||||
|
|
@ -100,25 +100,25 @@ type
|
||||||
## whose value may be set by the user to affect the subsequent
|
## whose value may be set by the user to affect the subsequent
|
||||||
## behavior of floating-point arithmetic.
|
## behavior of floating-point arithmetic.
|
||||||
|
|
||||||
TFTW* {.importc: "struct FTW", header: "<ftw.h>".} = record
|
TFTW* {.importc: "struct FTW", header: "<ftw.h>", final.} = object
|
||||||
base*: cint
|
base*: cint
|
||||||
level*: cint
|
level*: cint
|
||||||
|
|
||||||
TGlob* {.importc: "glob_t", header: "<glob.h>".} = record
|
TGlob* {.importc: "glob_t", header: "<glob.h>", final.} = object
|
||||||
gl_pathc*: int ## Count of paths matched by pattern.
|
gl_pathc*: int ## Count of paths matched by pattern.
|
||||||
gl_pathv*: ptr cstring ## Pointer to a list of matched pathnames.
|
gl_pathv*: ptr cstring ## Pointer to a list of matched pathnames.
|
||||||
gl_offs*: int ## Slots to reserve at the beginning of gl_pathv.
|
gl_offs*: int ## Slots to reserve at the beginning of gl_pathv.
|
||||||
|
|
||||||
TGroup* {.importc: "struct group", header: "<grp.h>".} = record
|
TGroup* {.importc: "struct group", header: "<grp.h>", final.} = object
|
||||||
gr_name*: cstring ## The name of the group.
|
gr_name*: cstring ## The name of the group.
|
||||||
gr_gid*: TGid ## Numerical group ID.
|
gr_gid*: TGid ## Numerical group ID.
|
||||||
gr_mem*: cstringArray ## Pointer to a null-terminated array of character
|
gr_mem*: cstringArray ## Pointer to a null-terminated array of character
|
||||||
## pointers to member names.
|
## pointers to member names.
|
||||||
|
|
||||||
Ticonv* {.importc: "iconv_t", header: "<iconv.h>".} =
|
Ticonv* {.importc: "iconv_t", header: "<iconv.h>", final.} =
|
||||||
record ## Identifies the conversion from one codeset to another.
|
object ## Identifies the conversion from one codeset to another.
|
||||||
|
|
||||||
Tlconv* {.importc: "struct lconv", header: "<locale.h>".} = record
|
Tlconv* {.importc: "struct lconv", header: "<locale.h>", final.} = object
|
||||||
currency_symbol*: cstring
|
currency_symbol*: cstring
|
||||||
decimal_point*: cstring
|
decimal_point*: cstring
|
||||||
frac_digits*: char
|
frac_digits*: char
|
||||||
|
|
@ -144,14 +144,14 @@ type
|
||||||
p_sign_posn*: char
|
p_sign_posn*: char
|
||||||
thousands_sep*: cstring
|
thousands_sep*: cstring
|
||||||
|
|
||||||
TMqd* {.importc: "mqd_t", header: "<mqueue.h>".} = record
|
TMqd* {.importc: "mqd_t", header: "<mqueue.h>", final.} = object
|
||||||
TMqAttr* {.importc: "struct mq_attr", header: "<mqueue.h>".} = record
|
TMqAttr* {.importc: "struct mq_attr", header: "<mqueue.h>", final.} = object
|
||||||
mq_flags*: int ## Message queue flags.
|
mq_flags*: int ## Message queue flags.
|
||||||
mq_maxmsg*: int ## Maximum number of messages.
|
mq_maxmsg*: int ## Maximum number of messages.
|
||||||
mq_msgsize*: int ## Maximum message size.
|
mq_msgsize*: int ## Maximum message size.
|
||||||
mq_curmsgs*: int ## Number of messages currently queued.
|
mq_curmsgs*: int ## Number of messages currently queued.
|
||||||
|
|
||||||
TPasswd* {.importc: "struct passwd", header: "<pwd.h>".} = record
|
TPasswd* {.importc: "struct passwd", header: "<pwd.h>", final.} = object
|
||||||
pw_name*: cstring ## User's login name.
|
pw_name*: cstring ## User's login name.
|
||||||
pw_uid*: TUid ## Numerical user ID.
|
pw_uid*: TUid ## Numerical user ID.
|
||||||
pw_gid*: TGid ## Numerical group ID.
|
pw_gid*: TGid ## Numerical group ID.
|
||||||
|
|
@ -198,7 +198,7 @@ type
|
||||||
Tuid* {.importc: "uid_t", header: "<sys/types.h>".} = int
|
Tuid* {.importc: "uid_t", header: "<sys/types.h>".} = int
|
||||||
Tuseconds* {.importc: "useconds_t", header: "<sys/types.h>".} = int
|
Tuseconds* {.importc: "useconds_t", header: "<sys/types.h>".} = int
|
||||||
|
|
||||||
Tutsname* {.importc: "struct utsname", header: "<sys/utsname.h>".} = record
|
Tutsname* {.importc: "struct utsname", header: "<sys/utsname.h>", final.} = object
|
||||||
sysname*, ## Name of this implementation of the operating system.
|
sysname*, ## Name of this implementation of the operating system.
|
||||||
nodename*, ## Name of this node within the communications
|
nodename*, ## Name of this node within the communications
|
||||||
## network to which this node is attached, if any.
|
## network to which this node is attached, if any.
|
||||||
|
|
@ -207,15 +207,15 @@ type
|
||||||
machine*: array [0..255, char] ## Name of the hardware type on which the
|
machine*: array [0..255, char] ## Name of the hardware type on which the
|
||||||
## system is running.
|
## system is running.
|
||||||
|
|
||||||
TSem* {.importc: "sem_t", header: "<semaphore.h>".} = record
|
TSem* {.importc: "sem_t", header: "<semaphore.h>", final.} = object
|
||||||
Tipc_perm* {.importc: "struct ipc_perm", header: "<sys/ipc.h>".} = record
|
Tipc_perm* {.importc: "struct ipc_perm", header: "<sys/ipc.h>", final.} = object
|
||||||
uid*: tuid ## Owner's user ID.
|
uid*: tuid ## Owner's user ID.
|
||||||
gid*: tgid ## Owner's group ID.
|
gid*: tgid ## Owner's group ID.
|
||||||
cuid*: Tuid ## Creator's user ID.
|
cuid*: Tuid ## Creator's user ID.
|
||||||
cgid*: Tgid ## Creator's group ID.
|
cgid*: Tgid ## Creator's group ID.
|
||||||
mode*: TMode ## Read/write permission.
|
mode*: TMode ## Read/write permission.
|
||||||
|
|
||||||
TStat* {.importc: "struct stat", header: "<sys/stat.h>".} = record
|
TStat* {.importc: "struct stat", header: "<sys/stat.h>", final.} = object
|
||||||
st_dev*: TDev ## Device ID of device containing file.
|
st_dev*: TDev ## Device ID of device containing file.
|
||||||
st_ino*: TIno ## File serial number.
|
st_ino*: TIno ## File serial number.
|
||||||
st_mode*: TMode ## Mode of file (see below).
|
st_mode*: TMode ## Mode of file (see below).
|
||||||
|
|
@ -239,7 +239,7 @@ type
|
||||||
st_blocks*: Tblkcnt ## Number of blocks allocated for this object.
|
st_blocks*: Tblkcnt ## Number of blocks allocated for this object.
|
||||||
|
|
||||||
|
|
||||||
TStatvfs* {.importc: "struct statvfs", header: "<sys/statvfs.h>".} = record
|
TStatvfs* {.importc: "struct statvfs", header: "<sys/statvfs.h>", final.} = object
|
||||||
f_bsize*: int ## File system block size.
|
f_bsize*: int ## File system block size.
|
||||||
f_frsize*: int ## Fundamental file system block size.
|
f_frsize*: int ## Fundamental file system block size.
|
||||||
f_blocks*: Tfsblkcnt ## Total number of blocks on file system in units of f_frsize.
|
f_blocks*: Tfsblkcnt ## Total number of blocks on file system in units of f_frsize.
|
||||||
|
|
@ -255,10 +255,10 @@ type
|
||||||
f_namemax*: int ## Maximum filename length.
|
f_namemax*: int ## Maximum filename length.
|
||||||
|
|
||||||
Tposix_typed_mem_info* {.importc: "struct posix_typed_mem_info",
|
Tposix_typed_mem_info* {.importc: "struct posix_typed_mem_info",
|
||||||
header: "<sys/mman.h>".} = record
|
header: "<sys/mman.h>", final.} = object
|
||||||
posix_tmi_length*: int
|
posix_tmi_length*: int
|
||||||
|
|
||||||
Ttm* {.importc: "struct tm", header: "<time.h>".} = record
|
Ttm* {.importc: "struct tm", header: "<time.h>", final.} = object
|
||||||
tm_sec*: cint ## Seconds [0,60].
|
tm_sec*: cint ## Seconds [0,60].
|
||||||
tm_min*: cint ## Minutes [0,59].
|
tm_min*: cint ## Minutes [0,59].
|
||||||
tm_hour*: cint ## Hour [0,23].
|
tm_hour*: cint ## Hour [0,23].
|
||||||
|
|
@ -268,10 +268,10 @@ type
|
||||||
tm_wday*: cint ## Day of week [0,6] (Sunday =0).
|
tm_wday*: cint ## Day of week [0,6] (Sunday =0).
|
||||||
tm_yday*: cint ## Day of year [0,365].
|
tm_yday*: cint ## Day of year [0,365].
|
||||||
tm_isdst*: cint ## Daylight Savings flag.
|
tm_isdst*: cint ## Daylight Savings flag.
|
||||||
Ttimespec* {.importc: "struct timespec", header: "<time.h>".} = record
|
Ttimespec* {.importc: "struct timespec", header: "<time.h>", final.} = object
|
||||||
tv_sec*: Ttime ## Seconds.
|
tv_sec*: Ttime ## Seconds.
|
||||||
tv_nsec*: int ## Nanoseconds.
|
tv_nsec*: int ## Nanoseconds.
|
||||||
titimerspec* {.importc: "struct itimerspec", header: "<time.h>".} = record
|
titimerspec* {.importc: "struct itimerspec", header: "<time.h>", final.} = object
|
||||||
it_interval*: ttimespec ## Timer period.
|
it_interval*: ttimespec ## Timer period.
|
||||||
it_value*: ttimespec ## Timer expiration.
|
it_value*: ttimespec ## Timer expiration.
|
||||||
|
|
||||||
|
|
@ -279,19 +279,19 @@ type
|
||||||
## Possibly volatile-qualified integer type of an object that can be
|
## Possibly volatile-qualified integer type of an object that can be
|
||||||
## accessed as an atomic entity, even in the presence of asynchronous
|
## accessed as an atomic entity, even in the presence of asynchronous
|
||||||
## interrupts.
|
## interrupts.
|
||||||
Tsigset* {.importc: "sigset_t", header: "<signal.h>".} = record
|
Tsigset* {.importc: "sigset_t", header: "<signal.h>", final.} = object
|
||||||
|
|
||||||
TsigEvent* {.importc: "struct sigevent", header: "<signal.h>".} = record
|
TsigEvent* {.importc: "struct sigevent", header: "<signal.h>", final.} = object
|
||||||
sigev_notify*: cint ## Notification type.
|
sigev_notify*: cint ## Notification type.
|
||||||
sigev_signo*: cint ## Signal number.
|
sigev_signo*: cint ## Signal number.
|
||||||
sigev_value*: Tsigval ## Signal value.
|
sigev_value*: Tsigval ## Signal value.
|
||||||
sigev_notify_function*: proc (x: TSigval) {.noconv.} ## Notification function.
|
sigev_notify_function*: proc (x: TSigval) {.noconv.} ## Notification function.
|
||||||
sigev_notify_attributes*: ptr Tpthreadattr ## Notification attributes.
|
sigev_notify_attributes*: ptr Tpthreadattr ## Notification attributes.
|
||||||
|
|
||||||
TsigVal* {.importc: "union sigval", header: "<signal.h>".} = record
|
TsigVal* {.importc: "union sigval", header: "<signal.h>", final.} = object
|
||||||
sival_ptr*: pointer ## pointer signal value;
|
sival_ptr*: pointer ## pointer signal value;
|
||||||
## integer signal value not defined!
|
## integer signal value not defined!
|
||||||
TSigaction* {.importc: "struct sigaction", header: "<signal.h>".} = record
|
TSigaction* {.importc: "struct sigaction", header: "<signal.h>", final.} = object
|
||||||
sa_handler*: proc (x: cint) {.noconv.} ## Pointer to a signal-catching
|
sa_handler*: proc (x: cint) {.noconv.} ## Pointer to a signal-catching
|
||||||
## function or one of the macros
|
## function or one of the macros
|
||||||
## SIG_IGN or SIG_DFL.
|
## SIG_IGN or SIG_DFL.
|
||||||
|
|
@ -300,16 +300,16 @@ type
|
||||||
sa_flags*: cint ## Special flags.
|
sa_flags*: cint ## Special flags.
|
||||||
sa_sigaction*: proc (x: cint, y: var TSigInfo, z: pointer) {.noconv.}
|
sa_sigaction*: proc (x: cint, y: var TSigInfo, z: pointer) {.noconv.}
|
||||||
|
|
||||||
TStack* {.importc: "stack_t", header: "<signal.h>".} = record
|
TStack* {.importc: "stack_t", header: "<signal.h>", final.} = object
|
||||||
ss_sp*: pointer ## Stack base or pointer.
|
ss_sp*: pointer ## Stack base or pointer.
|
||||||
ss_size*: int ## Stack size.
|
ss_size*: int ## Stack size.
|
||||||
ss_flags*: cint ## Flags.
|
ss_flags*: cint ## Flags.
|
||||||
|
|
||||||
TSigStack* {.importc: "struct sigstack", header: "<signal.h>".} = record
|
TSigStack* {.importc: "struct sigstack", header: "<signal.h>", final.} = object
|
||||||
ss_onstack*: cint ## Non-zero when signal stack is in use.
|
ss_onstack*: cint ## Non-zero when signal stack is in use.
|
||||||
ss_sp*: pointer ## Signal stack pointer.
|
ss_sp*: pointer ## Signal stack pointer.
|
||||||
|
|
||||||
TsigInfo* {.importc: "siginfo_t", header: "<signal.h>".} = record
|
TsigInfo* {.importc: "siginfo_t", header: "<signal.h>", final.} = object
|
||||||
si_signo*: cint ## Signal number.
|
si_signo*: cint ## Signal number.
|
||||||
si_code*: cint ## Signal code.
|
si_code*: cint ## Signal code.
|
||||||
si_errno*: cint ## If non-zero, an errno value associated with
|
si_errno*: cint ## If non-zero, an errno value associated with
|
||||||
|
|
@ -324,7 +324,7 @@ type
|
||||||
Tnl_item* {.importc: "nl_item", header: "<nl_types.h>".} = cint
|
Tnl_item* {.importc: "nl_item", header: "<nl_types.h>".} = cint
|
||||||
Tnl_catd* {.importc: "nl_catd", header: "<nl_types.h>".} = cint
|
Tnl_catd* {.importc: "nl_catd", header: "<nl_types.h>".} = cint
|
||||||
|
|
||||||
Tsched_param* {.importc: "struct sched_param", header: "<sched.h>".} = record
|
Tsched_param* {.importc: "struct sched_param", header: "<sched.h>", final.} = object
|
||||||
sched_priority*: cint
|
sched_priority*: cint
|
||||||
sched_ss_low_priority*: cint ## Low scheduling priority for
|
sched_ss_low_priority*: cint ## Low scheduling priority for
|
||||||
## sporadic server.
|
## sporadic server.
|
||||||
|
|
@ -334,15 +334,15 @@ type
|
||||||
sched_ss_max_repl*: cint ## Maximum pending replenishments for
|
sched_ss_max_repl*: cint ## Maximum pending replenishments for
|
||||||
## sporadic server.
|
## sporadic server.
|
||||||
|
|
||||||
Ttimeval* {.importc: "struct timeval", header: "<sys/select.h>".} = record
|
Ttimeval* {.importc: "struct timeval", header: "<sys/select.h>", final.} = object
|
||||||
tv_sec*: ttime ## Seconds.
|
tv_sec*: ttime ## Seconds.
|
||||||
tv_usec*: tsuseconds ## Microseconds.
|
tv_usec*: tsuseconds ## Microseconds.
|
||||||
Tfd_set* {.importc: "struct fd_set", header: "<sys/select.h>".} = record
|
Tfd_set* {.importc: "struct fd_set", header: "<sys/select.h>", final.} = object
|
||||||
|
|
||||||
Tposix_spawnattr* {.importc: "posix_spawnattr_t", header: "<spawn.h>".} = cint
|
Tposix_spawnattr* {.importc: "posix_spawnattr_t", header: "<spawn.h>".} = cint
|
||||||
Tposix_spawn_file_actions* {.importc: "posix_spawn_file_actions_t", header: "<spawn.h>".} = cint
|
Tposix_spawn_file_actions* {.importc: "posix_spawn_file_actions_t", header: "<spawn.h>".} = cint
|
||||||
Tmcontext* {.importc: "mcontext_t", header: "<ucontext.h>".} = record
|
Tmcontext* {.importc: "mcontext_t", header: "<ucontext.h>", final.} = object
|
||||||
Tucontext* {.importc: "ucontext_t", header: "<ucontext.h>".} = record
|
Tucontext* {.importc: "ucontext_t", header: "<ucontext.h>", final.} = object
|
||||||
uc_link*: ptr Tucontext ## Pointer to the context that is resumed
|
uc_link*: ptr Tucontext ## Pointer to the context that is resumed
|
||||||
## when this context returns.
|
## when this context returns.
|
||||||
uc_sigmask*: Tsigset ## The set of signals that are blocked when this
|
uc_sigmask*: Tsigset ## The set of signals that are blocked when this
|
||||||
|
|
@ -729,7 +729,7 @@ var
|
||||||
GLOB_NOSORT* {.importc, header: "<glob.h>".}: cint
|
GLOB_NOSORT* {.importc, header: "<glob.h>".}: cint
|
||||||
## Do not sort the pathnames returned.
|
## Do not sort the pathnames returned.
|
||||||
GLOB_ABORTED* {.importc, header: "<glob.h>".}: cint
|
GLOB_ABORTED* {.importc, header: "<glob.h>".}: cint
|
||||||
## The scan was stopped because GLOB_ERR was set or (*errfunc)()
|
## The scan was stopped because GLOB_ERR was set or errfunc()
|
||||||
## returned non-zero.
|
## returned non-zero.
|
||||||
GLOB_NOMATCH* {.importc, header: "<glob.h>".}: cint
|
GLOB_NOMATCH* {.importc, header: "<glob.h>".}: cint
|
||||||
## The pattern does not match any existing pathname, and GLOB_NOCHECK
|
## The pattern does not match any existing pathname, and GLOB_NOCHECK
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
# Nimrod's Runtime Library
|
# Nimrod's Runtime Library
|
||||||
# (c) Copyright 2006 Andreas Rumpf
|
# (c) Copyright 2008 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,7 +18,7 @@ type
|
||||||
PPointer = ptr pointer
|
PPointer = ptr pointer
|
||||||
|
|
||||||
TCollectorData = int
|
TCollectorData = int
|
||||||
TCell = record
|
TCell {.final.} = object
|
||||||
refcount: TCollectorData # the refcount and bit flags
|
refcount: TCollectorData # the refcount and bit flags
|
||||||
typ: PNimType
|
typ: PNimType
|
||||||
stackcount: int # stack counter for debugging
|
stackcount: int # stack counter for debugging
|
||||||
|
|
@ -67,18 +67,18 @@ type
|
||||||
|
|
||||||
TBitIndex = range[0..UnitsPerPage-1]
|
TBitIndex = range[0..UnitsPerPage-1]
|
||||||
|
|
||||||
TPageDesc = record
|
TPageDesc {.final.} = object
|
||||||
next: PPageDesc # all nodes are connected with this pointer
|
next: PPageDesc # all nodes are connected with this pointer
|
||||||
key: TAddress # start address at bit 0
|
key: TAddress # start address at bit 0
|
||||||
bits: array[TBitIndex, int] # a bit vector
|
bits: array[TBitIndex, int] # a bit vector
|
||||||
|
|
||||||
PPageDescArray = ptr array[0..1000_000, PPageDesc]
|
PPageDescArray = ptr array[0..1000_000, PPageDesc]
|
||||||
TCellSet = record
|
TCellSet {.final.} = object
|
||||||
counter, max: int
|
counter, max: int
|
||||||
head: PPageDesc
|
head: PPageDesc
|
||||||
data: PPageDescArray
|
data: PPageDescArray
|
||||||
|
|
||||||
TSetNode = record
|
TSetNode {.final.} = object
|
||||||
n: array[0.. (1 shl bitsPerNode)-1, PSetNode]
|
n: array[0.. (1 shl bitsPerNode)-1, PSetNode]
|
||||||
PSetNode = ptr TSetNode
|
PSetNode = ptr TSetNode
|
||||||
|
|
||||||
|
|
|
||||||
26
lib/repr.nim
26
lib/repr.nim
|
|
@ -81,9 +81,9 @@ proc reprSetAux(result: var string, p: pointer, typ: PNimType) =
|
||||||
of 1: u = ze64(cast[ptr int8](p)^)
|
of 1: u = ze64(cast[ptr int8](p)^)
|
||||||
of 2: u = ze64(cast[ptr int16](p)^)
|
of 2: u = ze64(cast[ptr int16](p)^)
|
||||||
of 4: u = ze64(cast[ptr int32](p)^)
|
of 4: u = ze64(cast[ptr int32](p)^)
|
||||||
of 8: u = ze64(cast[ptr int64](p)^)
|
of 8: u = cast[ptr int64](p)^
|
||||||
else:
|
else:
|
||||||
var a = cast[pbyteArray](p)^
|
var a = cast[pbyteArray](p)
|
||||||
for i in 0 .. typ.size*8-1:
|
for i in 0 .. typ.size*8-1:
|
||||||
if (a[i div 8] and (1 shl (i mod 8))) != 0:
|
if (a[i div 8] and (1 shl (i mod 8))) != 0:
|
||||||
if elemCounter > 0: add result, ", "
|
if elemCounter > 0: add result, ", "
|
||||||
|
|
@ -102,7 +102,7 @@ proc reprSet(p: pointer, typ: PNimType): string {.compilerproc.} =
|
||||||
reprSetAux(result, p, typ)
|
reprSetAux(result, p, typ)
|
||||||
|
|
||||||
type
|
type
|
||||||
TReprClosure = record # we cannot use a global variable here
|
TReprClosure {.final.} = object # we cannot use a global variable here
|
||||||
# as this wouldn't be thread-safe
|
# as this wouldn't be thread-safe
|
||||||
marked: TCellSet
|
marked: TCellSet
|
||||||
recdepth: int # do not recurse endless
|
recdepth: int # do not recurse endless
|
||||||
|
|
@ -189,8 +189,8 @@ proc reprAux(result: var string, p: pointer, typ: PNimType,
|
||||||
case typ.kind
|
case typ.kind
|
||||||
of tySet: reprSetAux(result, p, typ)
|
of tySet: reprSetAux(result, p, typ)
|
||||||
of tyArray: reprArray(result, p, typ, cl)
|
of tyArray: reprArray(result, p, typ, cl)
|
||||||
of tyRecord: reprRecord(result, p, typ, cl)
|
of tyTuple, tyPureObject: reprRecord(result, p, typ, cl)
|
||||||
of tyObject: # result = reprRecord(p, typ, cl)
|
of tyObject:
|
||||||
var t = cast[ptr PNimType](p)^
|
var t = cast[ptr PNimType](p)^
|
||||||
reprRecord(result, p, t, cl)
|
reprRecord(result, p, t, cl)
|
||||||
of tyRef, tyPtr:
|
of tyRef, tyPtr:
|
||||||
|
|
@ -220,14 +220,28 @@ proc reprAux(result: var string, p: pointer, typ: PNimType,
|
||||||
add result, "(invalid data!)"
|
add result, "(invalid data!)"
|
||||||
inc(cl.recdepth)
|
inc(cl.recdepth)
|
||||||
|
|
||||||
|
proc reprOpenArray(p: pointer, length: int, elemtyp: PNimType): string {.
|
||||||
|
compilerproc.} =
|
||||||
|
var
|
||||||
|
cl: TReprClosure
|
||||||
|
initReprClosure(cl)
|
||||||
|
result = "["
|
||||||
|
var bs = elemtyp.size
|
||||||
|
for i in 0..length - 1:
|
||||||
|
if i > 0: add result, ", "
|
||||||
|
reprAux(result, cast[pointer](cast[TAddress](p) + i*bs), elemtyp, cl)
|
||||||
|
add result, "]"
|
||||||
|
deinitReprClosure(cl)
|
||||||
|
|
||||||
proc reprAny(p: pointer, typ: PNimType): string =
|
proc reprAny(p: pointer, typ: PNimType): string =
|
||||||
var
|
var
|
||||||
cl: TReprClosure
|
cl: TReprClosure
|
||||||
initReprClosure(cl)
|
initReprClosure(cl)
|
||||||
result = ""
|
result = ""
|
||||||
if typ.kind in {tyObject, tyRecord, tyArray, tySet}:
|
if typ.kind in {tyObject, tyPureObject, tyTuple, tyArray, tySet}:
|
||||||
reprAux(result, p, typ, cl)
|
reprAux(result, p, typ, cl)
|
||||||
else:
|
else:
|
||||||
|
var p = p
|
||||||
reprAux(result, addr(p), typ, cl)
|
reprAux(result, addr(p), typ, cl)
|
||||||
add result, "\n"
|
add result, "\n"
|
||||||
deinitReprClosure(cl)
|
deinitReprClosure(cl)
|
||||||
|
|
|
||||||
|
|
@ -7,10 +7,10 @@
|
||||||
# distribution, for details about the copyright.
|
# distribution, for details about the copyright.
|
||||||
#
|
#
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## This module contains various string utility routines.
|
## This module contains various string utility routines.
|
||||||
## See the module `regexprs` for regular expression support.
|
## See the module `regexprs` for regular expression support.
|
||||||
|
## All the routines here are avaiable for the EMCAScript target
|
||||||
|
## too!
|
||||||
|
|
||||||
{.push debugger:off .} # the user does not want to trace a part
|
{.push debugger:off .} # the user does not want to trace a part
|
||||||
# of the standard library!
|
# of the standard library!
|
||||||
|
|
@ -153,6 +153,10 @@ proc ParseInt*(s: string): int {.noSideEffect.}
|
||||||
## a valid integer, `EInvalidValue` is raised.
|
## a valid integer, `EInvalidValue` is raised.
|
||||||
# XXX: make this biggestint!
|
# XXX: make this biggestint!
|
||||||
|
|
||||||
|
proc ParseBiggestInt*(s: string): biggestInt {.noSideEffect.}
|
||||||
|
## Parses a decimal integer value contained in `s`. If `s` is not
|
||||||
|
## a valid integer, `EInvalidValue` is raised.
|
||||||
|
|
||||||
proc ParseFloat*(s: string): float {.noSideEffect.}
|
proc ParseFloat*(s: string): float {.noSideEffect.}
|
||||||
## Parses a decimal floating point value contained in `s`. If `s` is not
|
## Parses a decimal floating point value contained in `s`. If `s` is not
|
||||||
## a valid floating point number, `EInvalidValue` is raised.
|
## a valid floating point number, `EInvalidValue` is raised.
|
||||||
|
|
@ -213,7 +217,13 @@ proc allCharsInSet*(s: string, theSet: TCharSet): bool =
|
||||||
if not (c in theSet): return false
|
if not (c in theSet): return false
|
||||||
return true
|
return true
|
||||||
|
|
||||||
proc c_strcmp(a, b: CString): int {.importc: "strcmp", nodecl.}
|
proc quoteIfSpaceExists*(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] != '"':
|
||||||
|
result = '"' & s & '"'
|
||||||
|
else:
|
||||||
|
result = s
|
||||||
|
|
||||||
proc startsWith(s, prefix: string): bool =
|
proc startsWith(s, prefix: string): bool =
|
||||||
var i = 0
|
var i = 0
|
||||||
|
|
@ -306,11 +316,9 @@ proc `%`(formatstr: string, a: openarray[string]): string =
|
||||||
|
|
||||||
proc cmpIgnoreCase(a, b: string): int =
|
proc cmpIgnoreCase(a, b: string): int =
|
||||||
# makes usage of the fact that strings are zero-terminated
|
# makes usage of the fact that strings are zero-terminated
|
||||||
var
|
|
||||||
aa, bb: char
|
|
||||||
for i in 0..len(a)-1:
|
for i in 0..len(a)-1:
|
||||||
aa = toLower(a[i])
|
var aa = toLower(a[i])
|
||||||
bb = toLower(b[i])
|
var bb = toLower(b[i])
|
||||||
result = ord(aa) - ord(bb)
|
result = ord(aa) - ord(bb)
|
||||||
if result != 0: break
|
if result != 0: break
|
||||||
|
|
||||||
|
|
@ -319,14 +327,13 @@ proc cmpIgnoreCase(a, b: string): int =
|
||||||
|
|
||||||
proc cmpIgnoreStyle(a, b: string): int =
|
proc cmpIgnoreStyle(a, b: string): int =
|
||||||
var
|
var
|
||||||
aa, bb: char
|
|
||||||
i = 0
|
i = 0
|
||||||
j = 0
|
j = 0
|
||||||
while True:
|
while True:
|
||||||
while a[i] == '_': inc(i)
|
while a[i] == '_': inc(i)
|
||||||
while b[j] == '_': inc(j) # BUGFIX: typo
|
while b[j] == '_': inc(j) # BUGFIX: typo
|
||||||
aa = toLower(a[i])
|
var aa = toLower(a[i])
|
||||||
bb = toLower(b[j])
|
var bb = toLower(b[j])
|
||||||
result = ord(aa) - ord(bb)
|
result = ord(aa) - ord(bb)
|
||||||
if result != 0 or aa == '\0': break
|
if result != 0 or aa == '\0': break
|
||||||
inc(i)
|
inc(i)
|
||||||
|
|
@ -475,15 +482,12 @@ proc deleteStr(s: var string, first, last: int) =
|
||||||
|
|
||||||
# parsing numbers:
|
# parsing numbers:
|
||||||
|
|
||||||
proc sprintf(buf, frmt: CString) {.nodecl, importc: "sprintf", varargs.}
|
|
||||||
|
|
||||||
proc toHex(x: BiggestInt, len: int): string =
|
proc toHex(x: BiggestInt, len: int): string =
|
||||||
const
|
const
|
||||||
HexChars = "0123456789ABCDEF"
|
HexChars = "0123456789ABCDEF"
|
||||||
var
|
var
|
||||||
shift: BiggestInt
|
shift: BiggestInt
|
||||||
result = newString(len)
|
result = newString(len)
|
||||||
shift = 0
|
|
||||||
for j in countdown(len-1, 0):
|
for j in countdown(len-1, 0):
|
||||||
result[j] = HexChars[toU32(x shr shift) and 0xF]
|
result[j] = HexChars[toU32(x shr shift) and 0xF]
|
||||||
shift = shift + 4
|
shift = shift + 4
|
||||||
|
|
@ -497,11 +501,8 @@ proc rawParseInt(s: string, index: var int): BiggestInt =
|
||||||
# one more valid negative than prositive integer. Thus we perform the
|
# one more valid negative than prositive integer. Thus we perform the
|
||||||
# computation as a negative number and then change the sign at the end.
|
# computation as a negative number and then change the sign at the end.
|
||||||
var
|
var
|
||||||
i: int
|
i: int = index # a local i is more efficient than accessing a var parameter
|
||||||
sign: BiggestInt
|
sign: BiggestInt = -1
|
||||||
i = index
|
|
||||||
# a local i is more efficient than accessing an in out parameter
|
|
||||||
sign = -1
|
|
||||||
if s[i] == '+':
|
if s[i] == '+':
|
||||||
inc(i)
|
inc(i)
|
||||||
elif s[i] == '-':
|
elif s[i] == '-':
|
||||||
|
|
@ -523,9 +524,7 @@ proc rawParseInt(s: string, index: var int): BiggestInt =
|
||||||
|
|
||||||
proc parseInt(s: string): int =
|
proc parseInt(s: string): int =
|
||||||
var
|
var
|
||||||
index: int
|
index: int = 0
|
||||||
res: BiggestInt
|
|
||||||
index = strStart
|
|
||||||
res = rawParseInt(s, index)
|
res = rawParseInt(s, index)
|
||||||
if index == -1:
|
if index == -1:
|
||||||
raise newException(EInvalidValue, "invalid integer: " & s)
|
raise newException(EInvalidValue, "invalid integer: " & s)
|
||||||
|
|
@ -535,17 +534,20 @@ proc parseInt(s: string): int =
|
||||||
else:
|
else:
|
||||||
result = int(res) # convert to smaller integer type
|
result = int(res) # convert to smaller integer type
|
||||||
|
|
||||||
|
proc ParseBiggestInt(s: string): biggestInt =
|
||||||
|
var
|
||||||
|
index: int = 0
|
||||||
|
result = rawParseInt(s, index)
|
||||||
|
if index == -1:
|
||||||
|
raise newException(EInvalidValue, "invalid integer: " & s)
|
||||||
|
|
||||||
proc ParseFloat(s: string): float =
|
proc ParseFloat(s: string): float =
|
||||||
var
|
var
|
||||||
hd, esign, sign: float
|
esign = 1.0
|
||||||
|
sign = 1.0
|
||||||
exponent, i: int
|
exponent, i: int
|
||||||
flags: int
|
flags: int
|
||||||
result = 0.0
|
result = 0.0
|
||||||
i = 0
|
|
||||||
exponent = 0
|
|
||||||
esign = 1.0
|
|
||||||
flags = 0
|
|
||||||
sign = 1.0
|
|
||||||
if s[i] == '+': inc(i)
|
if s[i] == '+': inc(i)
|
||||||
elif s[i] == '-':
|
elif s[i] == '-':
|
||||||
sign = -1.0
|
sign = -1.0
|
||||||
|
|
@ -558,7 +560,7 @@ proc ParseFloat(s: string): float =
|
||||||
while s[i] == '_': inc(i)
|
while s[i] == '_': inc(i)
|
||||||
# Decimal?
|
# Decimal?
|
||||||
if s[i] == '.':
|
if s[i] == '.':
|
||||||
hd = 1.0
|
var hd = 1.0
|
||||||
inc(i)
|
inc(i)
|
||||||
while s[i] in {'0'..'9'}:
|
while s[i] in {'0'..'9'}:
|
||||||
# Read fractional part
|
# Read fractional part
|
||||||
|
|
@ -586,7 +588,7 @@ proc ParseFloat(s: string): float =
|
||||||
inc(i)
|
inc(i)
|
||||||
while s[i] == '_': inc(i)
|
while s[i] == '_': inc(i)
|
||||||
# Calculate Exponent
|
# Calculate Exponent
|
||||||
hd = 1.0
|
var hd = 1.0
|
||||||
for j in 1..exponent:
|
for j in 1..exponent:
|
||||||
hd = hd * 10.0
|
hd = hd * 10.0
|
||||||
if esign > 0.0: result = result * hd
|
if esign > 0.0: result = result * hd
|
||||||
|
|
@ -600,11 +602,10 @@ proc toOct*(x: BiggestInt, len: int): string =
|
||||||
## converts `x` into its octal representation. The resulting string is
|
## converts `x` into its octal representation. The resulting string is
|
||||||
## always `len` characters long. No leading ``0c`` prefix is generated.
|
## always `len` characters long. No leading ``0c`` prefix is generated.
|
||||||
var
|
var
|
||||||
mask, shift: BiggestInt
|
mask: BiggestInt = 7
|
||||||
|
shift: BiggestInt = 0
|
||||||
assert(len > 0)
|
assert(len > 0)
|
||||||
result = newString(len)
|
result = newString(len)
|
||||||
mask = 7
|
|
||||||
shift = 0
|
|
||||||
for j in countdown(len-1, 0):
|
for j in countdown(len-1, 0):
|
||||||
result[j] = chr(int((x and mask) shr shift) + ord('0'))
|
result[j] = chr(int((x and mask) shr shift) + ord('0'))
|
||||||
shift = shift + 3
|
shift = shift + 3
|
||||||
|
|
@ -614,11 +615,10 @@ proc toBin*(x: BiggestInt, len: int): string =
|
||||||
## converts `x` into its binary representation. The resulting string is
|
## converts `x` into its binary representation. The resulting string is
|
||||||
## always `len` characters long. No leading ``0b`` prefix is generated.
|
## always `len` characters long. No leading ``0b`` prefix is generated.
|
||||||
var
|
var
|
||||||
mask, shift: BiggestInt
|
mask: BiggestInt = 1
|
||||||
|
shift: BiggestInt = 0
|
||||||
assert(len > 0)
|
assert(len > 0)
|
||||||
result = newString(len)
|
result = newString(len)
|
||||||
mask = 1
|
|
||||||
shift = 0
|
|
||||||
for j in countdown(len-1, 0):
|
for j in countdown(len-1, 0):
|
||||||
result[j] = chr(int((x and mask) shr shift) + ord('0'))
|
result[j] = chr(int((x and mask) shr shift) + ord('0'))
|
||||||
shift = shift + 1
|
shift = shift + 1
|
||||||
|
|
|
||||||
|
|
@ -33,10 +33,6 @@ var
|
||||||
IOFBF {.importc: "_IOFBF", nodecl.}: cint
|
IOFBF {.importc: "_IOFBF", nodecl.}: cint
|
||||||
IONBF {.importc: "_IONBF", nodecl.}: cint
|
IONBF {.importc: "_IONBF", nodecl.}: cint
|
||||||
|
|
||||||
# copied here to remove dependancy on strutils:
|
|
||||||
#proc toNimstr(x: Cstring, len: int): string {.
|
|
||||||
# noSideEffect, importc: "toNimStr".}
|
|
||||||
|
|
||||||
proc rawReadLine(f: TFile, result: var string) {.noStatic.} =
|
proc rawReadLine(f: TFile, result: var string) {.noStatic.} =
|
||||||
# of course this could be optimized a bit; but IO is slow anyway...
|
# of course this could be optimized a bit; but IO is slow anyway...
|
||||||
# and it was difficult to get this CORRECT with Ansi C's methods
|
# and it was difficult to get this CORRECT with Ansi C's methods
|
||||||
|
|
@ -81,6 +77,8 @@ proc write(f: TFile, b: bool) =
|
||||||
else: write(f, "false")
|
else: write(f, "false")
|
||||||
proc write(f: TFile, r: float) = fprintf(f, "%g", r)
|
proc write(f: TFile, r: float) = fprintf(f, "%g", r)
|
||||||
proc write(f: TFile, c: Char) = putc(c, f)
|
proc write(f: TFile, c: Char) = putc(c, f)
|
||||||
|
proc write(f: TFile, a: openArray[string]) =
|
||||||
|
for x in items(a): write(f, x)
|
||||||
|
|
||||||
proc EndOfFile(f: TFile): bool =
|
proc EndOfFile(f: TFile): bool =
|
||||||
# do not blame me; blame the ANSI C standard this is so brain-damaged
|
# do not blame me; blame the ANSI C standard this is so brain-damaged
|
||||||
|
|
@ -93,6 +91,11 @@ proc EndOfFile(f: TFile): bool =
|
||||||
proc writeln[Ty](f: TFile, x: Ty) =
|
proc writeln[Ty](f: TFile, x: Ty) =
|
||||||
write(f, x)
|
write(f, x)
|
||||||
write(f, "\n")
|
write(f, "\n")
|
||||||
|
|
||||||
|
proc writeln[Ty](f: TFile, x: openArray[Ty]) =
|
||||||
|
write(f, x)
|
||||||
|
write(f, "\n")
|
||||||
|
|
||||||
proc echo[Ty](x: Ty) = writeln(stdout, x)
|
proc echo[Ty](x: Ty) = writeln(stdout, x)
|
||||||
|
|
||||||
# interface to the C procs:
|
# interface to the C procs:
|
||||||
|
|
@ -128,7 +131,6 @@ proc ftell(f: TFile): int {.importc: "ftell", noDecl.}
|
||||||
|
|
||||||
proc fwrite(buf: Pointer, size, n: int, f: TFile): int {.
|
proc fwrite(buf: Pointer, size, n: int, f: TFile): int {.
|
||||||
importc: "fwrite", noDecl.}
|
importc: "fwrite", noDecl.}
|
||||||
# size_t fwrite(const void *ptr, size_t size, size_t n, FILE *stream);
|
|
||||||
|
|
||||||
proc readBuffer(f: TFile, buffer: pointer, len: int): int =
|
proc readBuffer(f: TFile, buffer: pointer, len: int): int =
|
||||||
result = fread(buffer, 1, len, f)
|
result = fread(buffer, 1, len, f)
|
||||||
|
|
@ -140,9 +142,11 @@ proc ReadChars(f: TFile, a: var openarray[char], start, len: int): int =
|
||||||
result = readBuffer(f, addr(a[start]), len)
|
result = readBuffer(f, addr(a[start]), len)
|
||||||
|
|
||||||
proc writeBytes(f: TFile, a: openarray[byte], start, len: int): int =
|
proc writeBytes(f: TFile, a: openarray[byte], start, len: int): int =
|
||||||
result = writeBuffer(f, addr(a[start]), len)
|
var x = cast[ptr array[0..1000_000_000, byte]](a)
|
||||||
|
result = writeBuffer(f, addr(x[start]), len)
|
||||||
proc writeChars(f: TFile, a: openarray[char], start, len: int): int =
|
proc writeChars(f: TFile, a: openarray[char], start, len: int): int =
|
||||||
result = writeBuffer(f, addr(a[start]), len)
|
var x = cast[ptr array[0..1000_000_000, byte]](a)
|
||||||
|
result = writeBuffer(f, addr(x[start]), len)
|
||||||
proc writeBuffer(f: TFile, buffer: pointer, len: int): int =
|
proc writeBuffer(f: TFile, buffer: pointer, len: int): int =
|
||||||
result = fwrite(buffer, 1, len, f)
|
result = fwrite(buffer, 1, len, f)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@
|
||||||
# the programmer may not want
|
# the programmer may not want
|
||||||
|
|
||||||
type
|
type
|
||||||
TStringDesc {.importc, nodecl.} = record
|
TStringDesc {.importc, nodecl, final.} = object
|
||||||
len, space: int # len and space without counting the terminating zero
|
len, space: int # len and space without counting the terminating zero
|
||||||
data: array[0..0, char] # for the '\0' character
|
data: array[0..0, char] # for the '\0' character
|
||||||
|
|
||||||
|
|
@ -25,7 +25,6 @@ type
|
||||||
# implementation:
|
# implementation:
|
||||||
|
|
||||||
proc resize(old: int): int {.inline.} =
|
proc resize(old: int): int {.inline.} =
|
||||||
assert(old < 65536 * 4)
|
|
||||||
if old <= 0: return 1
|
if old <= 0: return 1
|
||||||
elif old < 65536: return old * 2
|
elif old < 65536: return old * 2
|
||||||
else: return old * 3 div 2 # for large arrays * 3/2 is better
|
else: return old * 3 div 2 # for large arrays * 3/2 is better
|
||||||
|
|
@ -64,6 +63,7 @@ proc cstrToNimstr(str: CString): mstring {.compilerProc.} =
|
||||||
return toNimstr(str, c_strlen(str))
|
return toNimstr(str, c_strlen(str))
|
||||||
|
|
||||||
proc copyString(src: mstring): mstring {.compilerProc.} =
|
proc copyString(src: mstring): mstring {.compilerProc.} =
|
||||||
|
if src == nil: return nil
|
||||||
result = rawNewString(src.space)
|
result = rawNewString(src.space)
|
||||||
result.len = src.len
|
result.len = src.len
|
||||||
c_memcpy(result.data, src.data, (src.len + 1) * sizeof(Char))
|
c_memcpy(result.data, src.data, (src.len + 1) * sizeof(Char))
|
||||||
|
|
@ -220,7 +220,7 @@ proc setLengthSeq(seq: PGenericSeq, elemSize, newLen: int): PGenericSeq {.
|
||||||
result.len = newLen
|
result.len = newLen
|
||||||
|
|
||||||
# --------------- other string routines ----------------------------------
|
# --------------- other string routines ----------------------------------
|
||||||
proc `$`(x: int): string =
|
proc nimIntToStr(x: int): string {.compilerproc.} =
|
||||||
result = newString(sizeof(x)*4)
|
result = newString(sizeof(x)*4)
|
||||||
var i = 0
|
var i = 0
|
||||||
var y = x
|
var y = x
|
||||||
|
|
@ -238,14 +238,12 @@ proc `$`(x: int): string =
|
||||||
for j in 0..i div 2 - 1:
|
for j in 0..i div 2 - 1:
|
||||||
swap(result[j], result[i-j-1])
|
swap(result[j], result[i-j-1])
|
||||||
|
|
||||||
{.push warnings: off.}
|
proc nimFloatToStr(x: float): string {.compilerproc.} =
|
||||||
proc `$`(x: float): string =
|
|
||||||
var buf: array [0..59, char]
|
var buf: array [0..59, char]
|
||||||
c_sprintf(buf, "%#g", x)
|
c_sprintf(buf, "%#g", x)
|
||||||
return $buf
|
return $buf
|
||||||
{.pop.}
|
|
||||||
|
|
||||||
proc `$`(x: int64): string =
|
proc nimInt64ToStr(x: int64): string {.compilerproc.} =
|
||||||
# we don't rely on C's runtime here as some C compiler's
|
# we don't rely on C's runtime here as some C compiler's
|
||||||
# int64 support is weak
|
# int64 support is weak
|
||||||
result = newString(sizeof(x)*4)
|
result = newString(sizeof(x)*4)
|
||||||
|
|
@ -265,19 +263,13 @@ proc `$`(x: int64): string =
|
||||||
for j in 0..i div 2 - 1:
|
for j in 0..i div 2 - 1:
|
||||||
swap(result[j], result[i-j-1])
|
swap(result[j], result[i-j-1])
|
||||||
|
|
||||||
proc `$`(x: bool): string =
|
proc nimBoolToStr(x: bool): string {.compilerproc.} =
|
||||||
if x: result = "true"
|
return if x: "true" else: "false"
|
||||||
else: result = "false"
|
|
||||||
|
|
||||||
proc `$`(x: char): string =
|
proc nimCharToStr(x: char): string {.compilerproc.} =
|
||||||
result = newString(1)
|
result = newString(1)
|
||||||
result[0] = x
|
result[0] = x
|
||||||
|
|
||||||
proc `$`(x: string): string =
|
|
||||||
# this is useful for generic code!
|
|
||||||
return x
|
|
||||||
|
|
||||||
|
|
||||||
proc binaryStrSearch(x: openarray[string], y: string): int {.compilerproc.} =
|
proc binaryStrSearch(x: openarray[string], y: string): int {.compilerproc.} =
|
||||||
var
|
var
|
||||||
a = 0
|
a = 0
|
||||||
|
|
|
||||||
252
lib/system.nim
252
lib/system.nim
|
|
@ -86,7 +86,6 @@ type
|
||||||
## length field.
|
## length field.
|
||||||
seq*{.magic: "Seq".}[T] ## Generic type to construct sequences.
|
seq*{.magic: "Seq".}[T] ## Generic type to construct sequences.
|
||||||
set*{.magic: "Set".}[T] ## Generic type to construct bit sets.
|
set*{.magic: "Set".}[T] ## Generic type to construct bit sets.
|
||||||
tuple*{.magic: "Tuple".}[T] ## Generic type to construct tuple types.
|
|
||||||
|
|
||||||
Byte* = Int8 ## this is an alias for ``int8``, that is a signed
|
Byte* = Int8 ## this is an alias for ``int8``, that is a signed
|
||||||
## int 8 bits wide.
|
## int 8 bits wide.
|
||||||
|
|
@ -110,7 +109,8 @@ type
|
||||||
name*: cstring ## The exception's name is its Nimrod identifier.
|
name*: cstring ## The exception's name is its Nimrod identifier.
|
||||||
## This field is filled automatically in the
|
## This field is filled automatically in the
|
||||||
## ``raise`` statement.
|
## ``raise`` statement.
|
||||||
msg*: cstring ## the exception's message. Not providing an
|
msg* {.exportc: "message".}: cstring ## the exception's message. Not
|
||||||
|
## providing an
|
||||||
## exception message is bad style.
|
## exception message is bad style.
|
||||||
|
|
||||||
EAsynch* = object of E_Base ## Abstract exception class for
|
EAsynch* = object of E_Base ## Abstract exception class for
|
||||||
|
|
@ -129,16 +129,19 @@ type
|
||||||
## could not be fullfilled.
|
## could not be fullfilled.
|
||||||
EArithmetic* = object of ESynch ## raised if any kind of arithmetic
|
EArithmetic* = object of ESynch ## raised if any kind of arithmetic
|
||||||
## error occured.
|
## error occured.
|
||||||
EDivByZero* = object of EArithmetic ## is the exception class for integer
|
EDivByZero* {.compilerproc.} =
|
||||||
## divide-by-zero errors.
|
object of EArithmetic ## is the exception class for integer divide-by-zero
|
||||||
EOverflow* = object of EArithmetic ## is the exception class for integer
|
## errors.
|
||||||
## calculations whose results are too
|
EOverflow* {.compilerproc.} =
|
||||||
## large to fit in the provided bits.
|
object of EArithmetic ## is the exception class for integer calculations
|
||||||
|
## whose results are too large to fit in the
|
||||||
|
## provided bits.
|
||||||
|
|
||||||
EAccessViolation* = object of ESynch ## the exception class for
|
EAccessViolation* {.compilerproc.} =
|
||||||
## invalid memory access errors
|
object of ESynch ## the exception class for invalid memory access errors
|
||||||
|
|
||||||
EAssertionFailed* = object of ESynch ## is the exception class for Assert
|
EAssertionFailed* {.compilerproc.} =
|
||||||
|
object of ESynch ## is the exception class for Assert
|
||||||
## procedures that is raised if the
|
## procedures that is raised if the
|
||||||
## assertion proves wrong
|
## assertion proves wrong
|
||||||
|
|
||||||
|
|
@ -154,6 +157,9 @@ type
|
||||||
|
|
||||||
EInvalidIndex* = object of ESynch ## is raised if an array index is out
|
EInvalidIndex* = object of ESynch ## is raised if an array index is out
|
||||||
## of bounds.
|
## of bounds.
|
||||||
|
EInvalidField* = object of ESynch ## is raised if a record field is not
|
||||||
|
## accessible because its dicriminant's
|
||||||
|
## value does not fit.
|
||||||
|
|
||||||
EOutOfRange* = object of ESynch ## is raised if a range check error
|
EOutOfRange* = object of ESynch ## is raised if a range check error
|
||||||
## occured.
|
## occured.
|
||||||
|
|
@ -164,12 +170,12 @@ type
|
||||||
ENoExceptionToReraise* = object of ESynch ## is raised if there is no
|
ENoExceptionToReraise* = object of ESynch ## is raised if there is no
|
||||||
## exception to reraise.
|
## exception to reraise.
|
||||||
|
|
||||||
EInvalidObjectAssignment* = object of ESynch ## is raised if an object
|
EInvalidObjectAssignment* =
|
||||||
## gets assigned to its
|
object of ESynch ## is raised if an object gets assigned to its
|
||||||
## farther's object.
|
## farther's object.
|
||||||
|
|
||||||
EInvalidObjectConversion* = object of ESynch ## is raised if an object is
|
EInvalidObjectConversion* =
|
||||||
## converted to an incompatible
|
object of ESynch ## is raised if an object is converted to an incompatible
|
||||||
## object type.
|
## object type.
|
||||||
|
|
||||||
TResult* = enum Failure, Success
|
TResult* = enum Failure, Success
|
||||||
|
|
@ -394,7 +400,7 @@ proc in_Operator*[T](x: set[T], y: T): bool {.magic: "InSet", noSideEffect.}
|
||||||
## writeln(stdout, 'b' in s)
|
## writeln(stdout, 'b' in s)
|
||||||
##
|
##
|
||||||
## If ``in`` had been declared as ``[T](elem: T, s: set[T])`` then ``T`` would
|
## 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 with type
|
## 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
|
## ``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 ``in_operator``; ``in`` then
|
||||||
## passes its arguments in reverse order.
|
## passes its arguments in reverse order.
|
||||||
|
|
@ -418,25 +424,31 @@ proc cmp*(x, y: string): int {.noSideEffect.}
|
||||||
## Compare proc for strings. More efficient than the generic version.
|
## Compare proc for strings. More efficient than the generic version.
|
||||||
|
|
||||||
# concat operator:
|
# concat operator:
|
||||||
proc `&` * (x: string, y: char): string {.
|
proc `&` * (x: string, y: char): string {.magic: "ConStrStr", noSideEffect.}
|
||||||
magic: "ConStrStr", noSideEffect, returnsNew.}
|
proc `&` * (x: char, y: char): string {.magic: "ConStrStr", noSideEffect.}
|
||||||
proc `&` * (x: char, y: char): string {.
|
proc `&` * (x, y: string): string {.magic: "ConStrStr", noSideEffect.}
|
||||||
magic: "ConStrStr", noSideEffect, returnsNew.}
|
proc `&` * (x: char, y: string): string {.magic: "ConStrStr", noSideEffect.}
|
||||||
proc `&` * (x, y: string): string {.
|
## is the `concatenation operator`. It concatenates `x` and `y`.
|
||||||
magic: "ConStrStr", noSideEffect, returnsNew.}
|
|
||||||
proc `&` * (x: char, y: string): string {.
|
|
||||||
magic: "ConStrStr", noSideEffect, returnsNew.}
|
|
||||||
## is the `concatenation operator`. It
|
|
||||||
## concatenates `x` and `y`.
|
|
||||||
|
|
||||||
proc add * (x: var string, y: char) {.magic: "AppendStrCh".}
|
proc add * (x: var string, y: char) {.magic: "AppendStrCh".}
|
||||||
proc add * (x: var string, y: string) {.magic: "AppendStrStr".}
|
proc add * (x: var string, y: string) {.magic: "AppendStrStr".}
|
||||||
|
|
||||||
|
when not defined(ECMAScript):
|
||||||
proc add* (x: var string, y: cstring) =
|
proc add* (x: var string, y: cstring) =
|
||||||
var i = 0
|
var i = 0
|
||||||
while y[i] != '\0':
|
while y[i] != '\0':
|
||||||
add(x, y[i])
|
add(x, y[i])
|
||||||
inc(i)
|
inc(i)
|
||||||
|
else:
|
||||||
|
proc add* (x: var string, y: cstring) {.pure.} =
|
||||||
|
asm """
|
||||||
|
var len = `x`[0].length-1;
|
||||||
|
for (var i = 0; i < `y`.length; ++i) {
|
||||||
|
`x`[0][len] = `y`.charCodeAt(i);
|
||||||
|
++len;
|
||||||
|
}
|
||||||
|
`x`[0][len] = 0
|
||||||
|
"""
|
||||||
|
|
||||||
proc add *[T](x: var seq[T], y: T) {.magic: "AppendSeqElem".}
|
proc add *[T](x: var seq[T], y: T) {.magic: "AppendSeqElem".}
|
||||||
proc add *[T](x: var seq[T], y: seq[T]) {.magic: "AppendSeqSeq".}
|
proc add *[T](x: var seq[T], y: seq[T]) {.magic: "AppendSeqSeq".}
|
||||||
|
|
@ -675,20 +687,27 @@ proc swap*[T](a, b: var T) {.magic: "Swap".}
|
||||||
## swaps the values `a` and `b`. This is often more efficient than
|
## swaps the values `a` and `b`. This is often more efficient than
|
||||||
## ``tmp = a; a = b; b = tmp``. Particularly useful for sorting algorithms.
|
## ``tmp = a; a = b; b = tmp``. Particularly useful for sorting algorithms.
|
||||||
|
|
||||||
proc ze*(x: int8): int {.magic: "Ze", noSideEffect.}
|
proc ze*(x: int8): int {.magic: "Ze8ToI", noSideEffect.}
|
||||||
## zero extends a smaller integer type to ``int``. This treats `x` as
|
## zero extends a smaller integer type to ``int``. This treats `x` as
|
||||||
## unsigned.
|
## unsigned.
|
||||||
proc ze*(x: int16): int {.magic: "Ze", noSideEffect.}
|
proc ze*(x: int16): int {.magic: "Ze16ToI", noSideEffect.}
|
||||||
## zero extends a smaller integer type to ``int``. This treats `x` as
|
## zero extends a smaller integer type to ``int``. This treats `x` as
|
||||||
## unsigned.
|
## unsigned.
|
||||||
|
|
||||||
proc ze64*(x: int32): int64 {.magic: "Ze64", noSideEffect.}
|
proc ze64*(x: int8): int64 {.magic: "Ze8ToI64", noSideEffect.}
|
||||||
## zero extends a smaller integer type to ``int64``. This treats `x` as
|
## zero extends a smaller integer type to ``int64``. This treats `x` as
|
||||||
## unsigned.
|
## unsigned.
|
||||||
proc ze*(x: int): int64 {.magic: "Ze", noDecl, noSideEffect.}
|
proc ze64*(x: int16): int64 {.magic: "Ze16ToI64", noSideEffect.}
|
||||||
|
## zero extends a smaller integer type to ``int64``. This treats `x` as
|
||||||
|
## unsigned.
|
||||||
|
|
||||||
|
proc ze64*(x: int32): int64 {.magic: "Ze32ToI64", noSideEffect.}
|
||||||
|
## zero extends a smaller integer type to ``int64``. This treats `x` as
|
||||||
|
## unsigned.
|
||||||
|
proc ze64*(x: int): int64 {.magic: "ZeIToI64", noDecl, noSideEffect.}
|
||||||
## zero extends a smaller integer type to ``int64``. This treats `x` as
|
## zero extends a smaller integer type to ``int64``. This treats `x` as
|
||||||
## unsigned. Does nothing if the size of an ``int`` is the same as ``int64``.
|
## unsigned. Does nothing if the size of an ``int`` is the same as ``int64``.
|
||||||
## (This is the case an 64 bit processors.)
|
## (This is the case on 64 bit processors.)
|
||||||
|
|
||||||
proc toU8*(x: int): int8 {.magic: "ToU8", noSideEffect.}
|
proc toU8*(x: int): int8 {.magic: "ToU8", noSideEffect.}
|
||||||
## treats `x` as unsigned and converts it to a byte by taking the last 8 bits
|
## treats `x` as unsigned and converts it to a byte by taking the last 8 bits
|
||||||
|
|
@ -749,34 +768,34 @@ template `>%` *(x, y: expr): expr = y <% x
|
||||||
## treats `x` and `y` as unsigned and compares them.
|
## treats `x` and `y` as unsigned and compares them.
|
||||||
## Returns true iff ``unsigned(x) > unsigned(y)``.
|
## Returns true iff ``unsigned(x) > unsigned(y)``.
|
||||||
|
|
||||||
proc `$` *(x: int): string {.noSideEffect.}
|
proc `$` *(x: int): string {.magic: "IntToStr", noSideEffect.}
|
||||||
## The stingify operator for an integer argument. Returns `x`
|
## The stingify operator for an integer argument. Returns `x`
|
||||||
## converted to a decimal string.
|
## converted to a decimal string.
|
||||||
|
|
||||||
proc `$` *(x: int64): string {.noSideEffect.}
|
proc `$` *(x: int64): string {.magic: "Int64ToStr", noSideEffect.}
|
||||||
## The stingify operator for an integer argument. Returns `x`
|
## The stingify operator for an integer argument. Returns `x`
|
||||||
## converted to a decimal string.
|
## converted to a decimal string.
|
||||||
|
|
||||||
proc `$` *(x: float): string {.noSideEffect.}
|
proc `$` *(x: float): string {.magic: "FloatToStr", noSideEffect.}
|
||||||
## The stingify operator for a float argument. Returns `x`
|
## The stingify operator for a float argument. Returns `x`
|
||||||
## converted to a decimal string.
|
## converted to a decimal string.
|
||||||
|
|
||||||
proc `$` *(x: bool): string {.noSideEffect.}
|
proc `$` *(x: bool): string {.magic: "BoolToStr", noSideEffect.}
|
||||||
## The stingify operator for a boolean argument. Returns `x`
|
## The stingify operator for a boolean argument. Returns `x`
|
||||||
## converted to the string "false" or "true".
|
## converted to the string "false" or "true".
|
||||||
|
|
||||||
proc `$` *(x: char): string {.noSideEffect.}
|
proc `$` *(x: char): string {.magic: "CharToStr", noSideEffect.}
|
||||||
## The stingify operator for a character argument. Returns `x`
|
## The stingify operator for a character argument. Returns `x`
|
||||||
## converted to a string.
|
## converted to a string.
|
||||||
|
|
||||||
proc `$` *(x: Cstring): string {.noSideEffect, importc: "cstrToNimstr".}
|
proc `$` *(x: Cstring): string {.magic: "CStrToStr", noSideEffect.}
|
||||||
## The stingify operator for a CString argument. Returns `x`
|
## The stingify operator for a CString argument. Returns `x`
|
||||||
## converted to a string.
|
## converted to a string.
|
||||||
|
|
||||||
proc `$` *(x: string): string {.noSideEffect.}
|
proc `$` *(x: string): string {.magic: "StrToStr", noSideEffect.}
|
||||||
## The stingify operator for a string argument. Returns `x`
|
## The stingify operator for a string argument. Returns `x`
|
||||||
## as it is. This operator is useful for generic code, so
|
## as it is. This operator is useful for generic code, so
|
||||||
## that ``$expr`` works if ``expr`` is already a string.
|
## that ``$expr`` also works if ``expr`` is already a string.
|
||||||
|
|
||||||
# undocumented:
|
# undocumented:
|
||||||
proc getRefcount*[T](x: ref T): int {.importc: "getRefcount".}
|
proc getRefcount*[T](x: ref T): int {.importc: "getRefcount".}
|
||||||
|
|
@ -790,10 +809,12 @@ proc getCurrentExceptionMsg*(): string {.exportc.}
|
||||||
|
|
||||||
# new constants:
|
# new constants:
|
||||||
const
|
const
|
||||||
inf* = 1.0 / 0.0
|
inf* {.magic: "Inf".} = 0.0
|
||||||
## contains the IEEE floating point value of positive infinity.
|
## contains the IEEE floating point value of positive infinity.
|
||||||
nan* = 0.0 / 0.0
|
neginf* {.magic: "NegInf".} = 0.0
|
||||||
## contains the IEEE floating point value of *Not A Number*. Note
|
## contains the IEEE floating point value of negative infinity.
|
||||||
|
nan* {.magic: "NaN".} = 0.0
|
||||||
|
## contains an IEEE floating point value of *Not A Number*. Note
|
||||||
## that you cannot compare a floating point value to this value
|
## that you cannot compare a floating point value to this value
|
||||||
## and expect a reasonable result - use the `classify` procedure
|
## and expect a reasonable result - use the `classify` procedure
|
||||||
## in the module ``math`` for checking for NaN.
|
## in the module ``math`` for checking for NaN.
|
||||||
|
|
@ -885,11 +906,22 @@ iterator items*(a: cstring): char {.inline.} =
|
||||||
yield a[i]
|
yield a[i]
|
||||||
inc(i)
|
inc(i)
|
||||||
|
|
||||||
|
|
||||||
|
proc isNil*[T](x: seq[T]): bool {.noSideEffect, magic: "IsNil".}
|
||||||
|
proc isNil*[T](x: ref T): bool {.noSideEffect, magic: "IsNil".}
|
||||||
|
proc isNil*(x: string): bool {.noSideEffect, magic: "IsNil".}
|
||||||
|
proc isNil*[T](x: ptr T): bool {.noSideEffect, magic: "IsNil".}
|
||||||
|
proc isNil*(x: pointer): bool {.noSideEffect, magic: "IsNil".}
|
||||||
|
proc isNil*(x: cstring): bool {.noSideEffect, magic: "IsNil".}
|
||||||
|
## Fast check whether `x` is nil. This is sometimes more efficient than
|
||||||
|
## ``== nil``.
|
||||||
|
|
||||||
|
|
||||||
# Fixup some magic symbols here:
|
# Fixup some magic symbols here:
|
||||||
{.fixup_system.} # This is an undocumented pragma that can only be used
|
{.fixup_system.} # This is an undocumented pragma that can only be used
|
||||||
# once in the system module.
|
# once in the system module.
|
||||||
|
|
||||||
proc `&` *[T](x, y: seq[T]): seq[T] {.noSideEffect, returnsNew.} =
|
proc `&` *[T](x, y: seq[T]): seq[T] {.noSideEffect.} =
|
||||||
result = []
|
result = []
|
||||||
setLen(result, x.len + y.len)
|
setLen(result, x.len + y.len)
|
||||||
for i in 0..x.len-1:
|
for i in 0..x.len-1:
|
||||||
|
|
@ -897,41 +929,104 @@ proc `&` *[T](x, y: seq[T]): seq[T] {.noSideEffect, returnsNew.} =
|
||||||
for i in 0..y.len-1:
|
for i in 0..y.len-1:
|
||||||
result[i] = y[i]
|
result[i] = y[i]
|
||||||
|
|
||||||
proc `&` *[T](x: seq[T], y: T): seq[T] {.noSideEffect, returnsNew.} =
|
proc `&` *[T](x: seq[T], y: T): seq[T] {.noSideEffect.} =
|
||||||
result = []
|
result = []
|
||||||
setLen(x.len + 1)
|
setLen(x.len + 1)
|
||||||
for i in 0..x.len-1:
|
for i in 0..x.len-1:
|
||||||
result[i] = x[i]
|
result[i] = x[i]
|
||||||
result[x.len] = y
|
result[x.len] = y
|
||||||
|
|
||||||
proc `&` *[T](x: T, y: seq[T]): seq[T] {.noSideEffect, returnsNew.} =
|
proc `&` *[T](x: T, y: seq[T]): seq[T] {.noSideEffect.} =
|
||||||
result = []
|
result = []
|
||||||
setLen(y.len + 1)
|
setLen(y.len + 1)
|
||||||
for i in 0..y.len-1:
|
for i in 0..y.len-1:
|
||||||
result[i] = y[i]
|
result[i] = y[i]
|
||||||
result[y.len] = x
|
result[y.len] = x
|
||||||
|
|
||||||
proc `&` *[T](x, y: T): seq[T] {.noSideEffect, returnsNew.} =
|
proc `&` *[T](x, y: T): seq[T] {.noSideEffect.} =
|
||||||
return [x, y]
|
return [x, y]
|
||||||
|
|
||||||
|
when not defined(ECMAScript): # XXX make this local procs
|
||||||
|
proc seqToPtr*[T](x: seq[T]): pointer {.inline, nosideeffect.} =
|
||||||
|
result = cast[pointer](x)
|
||||||
|
else:
|
||||||
|
proc seqToPtr*[T](x: seq[T]): pointer {.pure, nosideeffect.} =
|
||||||
|
asm """return `x`"""
|
||||||
|
|
||||||
proc `==` *[T](x, y: seq[T]): bool {.noSideEffect.} =
|
proc `==` *[T](x, y: seq[T]): bool {.noSideEffect.} =
|
||||||
## Generic equals operator for sequences: relies on a equals operator for
|
## Generic equals operator for sequences: relies on a equals operator for
|
||||||
## the element type `T`.
|
## the element type `T`.
|
||||||
if cast[pointer](x) == cast[pointer](y):
|
if seqToPtr(x) == seqToPtr(y):
|
||||||
result = true
|
result = true
|
||||||
elif cast[pointer](x) == nil or cast[pointer](y) == nil:
|
elif seqToPtr(x) == nil or seqToPtr(y) == nil:
|
||||||
result = false
|
result = false
|
||||||
elif x.len == y.len:
|
elif x.len == y.len:
|
||||||
for i in 0..x.len-1:
|
for i in 0..x.len-1:
|
||||||
if x[i] != y[i]: return false
|
if x[i] != y[i]: return false
|
||||||
result = true
|
result = true
|
||||||
|
|
||||||
|
# ----------------- FPU ------------------------------------------------------
|
||||||
|
|
||||||
|
#proc disableFPUExceptions*()
|
||||||
|
# disables all floating point unit exceptions
|
||||||
|
|
||||||
|
#proc enableFPUExceptions*()
|
||||||
|
# enables all floating point unit exceptions
|
||||||
|
|
||||||
|
# ----------------- GC interface ---------------------------------------------
|
||||||
|
|
||||||
|
proc GC_disable*()
|
||||||
|
## disables the GC. If called n-times, n calls to `GC_enable` are needed to
|
||||||
|
## reactivate the GC. Note that in most circumstances one should only disable
|
||||||
|
## the mark and sweep phase with `GC_disableMarkAndSweep`.
|
||||||
|
|
||||||
|
proc GC_enable*()
|
||||||
|
## enables the GC again.
|
||||||
|
|
||||||
|
proc GC_fullCollect*()
|
||||||
|
## forces a full garbage collection pass.
|
||||||
|
## Ordinary code does not need to call this.
|
||||||
|
|
||||||
|
type
|
||||||
|
TGC_Strategy* = enum ## the strategy the GC should use for the application
|
||||||
|
gcThroughput, ## optimize for throughput
|
||||||
|
gcResponsiveness, ## optimize for responsiveness (default)
|
||||||
|
gcOptimizeTime, ## optimize for speed
|
||||||
|
gcOptimizeSpace ## optimize for memory footprint
|
||||||
|
|
||||||
|
proc GC_setStrategy*(strategy: TGC_Strategy)
|
||||||
|
## tells the GC the desired strategy for the application.
|
||||||
|
|
||||||
|
proc GC_enableMarkAndSweep*()
|
||||||
|
proc GC_disableMarkAndSweep*()
|
||||||
|
## the current implementation uses a reference counting garbage collector
|
||||||
|
## with a seldomly run mark and sweep phase to free cycles. The mark and
|
||||||
|
## sweep phase may take a long time and is not needed if the application
|
||||||
|
## does not create cycles. Thus the mark and sweep phase can be deactivated
|
||||||
|
## and activated separately from the rest of the GC.
|
||||||
|
|
||||||
|
|
||||||
{.push checks: off, line_dir: off, debugger: off,
|
{.push checks: off, line_dir: off, debugger: off,
|
||||||
assertions: on.} # obviously we cannot generate checking operations here :-)
|
assertions: on.} # obviously we cannot generate checking operations here :-)
|
||||||
# because it would yield into an endless recursion
|
# because it would yield into an endless recursion
|
||||||
# however, stack-traces are available for most parts
|
# however, stack-traces are available for most parts
|
||||||
# of the code
|
# of the code
|
||||||
|
|
||||||
|
proc echo*[Ty](x: 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
|
||||||
|
var
|
||||||
|
e: ref exceptn
|
||||||
|
new(e)
|
||||||
|
e.msg = message
|
||||||
|
e
|
||||||
|
|
||||||
|
when not defined(EcmaScript):
|
||||||
|
|
||||||
include hti
|
include hti
|
||||||
|
|
||||||
proc initGC()
|
proc initGC()
|
||||||
|
|
@ -968,52 +1063,10 @@ when defined(windows):
|
||||||
when defined(endb):
|
when defined(endb):
|
||||||
proc endbStep()
|
proc endbStep()
|
||||||
|
|
||||||
|
|
||||||
template newException(exceptn, message: expr): expr =
|
|
||||||
block: # open a new scope
|
|
||||||
var
|
|
||||||
e: ref exceptn
|
|
||||||
new(e)
|
|
||||||
e.msg = message
|
|
||||||
e
|
|
||||||
|
|
||||||
# ----------------- GC interface ---------------------------------------------
|
|
||||||
|
|
||||||
proc GC_disable*()
|
|
||||||
## disables the GC. If called n-times, n calls to `GC_enable` are needed to
|
|
||||||
## reactivate the GC. Note that in most circumstances one should only disable
|
|
||||||
## the mark and sweep phase with `GC_disableMarkAndSweep`.
|
|
||||||
|
|
||||||
proc GC_enable*()
|
|
||||||
## enables the GC again.
|
|
||||||
|
|
||||||
proc GC_fullCollect*()
|
|
||||||
## forces a full garbage collection pass.
|
|
||||||
## Ordinary code does not need to call this.
|
|
||||||
|
|
||||||
type
|
|
||||||
TGC_Strategy* = enum ## the strategy the GC should use for the application
|
|
||||||
gcThroughput , ## optimize for throughput
|
|
||||||
gcResponsiveness, ## optimize for responsiveness (default)
|
|
||||||
gcOptimizeTime, ## optimize for speed
|
|
||||||
gcOptimizeSpace ## optimize for memory footprint
|
|
||||||
|
|
||||||
proc GC_setStrategy*(strategy: TGC_Strategy)
|
|
||||||
## tells the GC the desired strategy for the application.
|
|
||||||
|
|
||||||
proc GC_enableMarkAndSweep*()
|
|
||||||
proc GC_disableMarkAndSweep*()
|
|
||||||
## the current implementation uses a reference counting garbage collector
|
|
||||||
## with a seldomly run mark and sweep phase to free cycles. The mark and
|
|
||||||
## sweep phase may take a long time and is not needed if the application
|
|
||||||
## does not create cycles. Thus the mark and sweep phase can be deactivated
|
|
||||||
## and activated separately from the rest of the GC.
|
|
||||||
|
|
||||||
|
|
||||||
# ----------------- IO Part --------------------------------------------------
|
# ----------------- IO Part --------------------------------------------------
|
||||||
|
|
||||||
type
|
type
|
||||||
CFile {.importc: "FILE", nodecl.} = record # empty record for
|
CFile {.importc: "FILE", nodecl, final.} = object # empty record for
|
||||||
# data hiding
|
# data hiding
|
||||||
TFile* = ptr CFile ## The type representing a file handle.
|
TFile* = ptr CFile ## The type representing a file handle.
|
||||||
|
|
||||||
|
|
@ -1075,6 +1128,7 @@ proc write*(f: TFile, s: string)
|
||||||
proc write*(f: TFile, b: Bool)
|
proc write*(f: TFile, b: Bool)
|
||||||
proc write*(f: TFile, c: char)
|
proc write*(f: TFile, c: char)
|
||||||
proc write*(f: TFile, c: cstring)
|
proc write*(f: TFile, c: cstring)
|
||||||
|
proc write*(f: TFile, a: openArray[string])
|
||||||
## Writes a value to the file `f`. May throw an IO exception.
|
## Writes a value to the file `f`. May throw an IO exception.
|
||||||
|
|
||||||
proc readLine*(f: TFile): string
|
proc readLine*(f: TFile): string
|
||||||
|
|
@ -1084,9 +1138,12 @@ proc readLine*(f: TFile): string
|
||||||
## ``CRLF``. The newline character(s) are not part of the returned string.
|
## ``CRLF``. The newline character(s) are not part of the returned string.
|
||||||
|
|
||||||
proc writeln*[Ty](f: TFile, x: Ty) {.inline.}
|
proc writeln*[Ty](f: TFile, x: Ty) {.inline.}
|
||||||
## writes a value `x` to `f` and then writes "\n". May throw an IO exception.
|
## writes a value `x` to `f` and then writes "\n".
|
||||||
proc echo*[Ty](x: Ty) {.inline.}
|
## May throw an IO exception.
|
||||||
## equivalent to ``writeln(stdout, x); flush(stdout)``.
|
|
||||||
|
proc writeln*[Ty](f: TFile, x: openArray[Ty]) {.inline.}
|
||||||
|
## writes a value `x` to `f` and then writes "\n".
|
||||||
|
## May throw an IO exception.
|
||||||
|
|
||||||
proc getFileSize*(f: TFile): int64
|
proc getFileSize*(f: TFile): int64
|
||||||
## retrieves the file size (in bytes) of `f`.
|
## retrieves the file size (in bytes) of `f`.
|
||||||
|
|
@ -1154,7 +1211,7 @@ include arithm
|
||||||
|
|
||||||
# sequence type declarations here because the GC needs them too:
|
# sequence type declarations here because the GC needs them too:
|
||||||
type
|
type
|
||||||
TGenericSeq {.importc, nodecl.} = record
|
TGenericSeq {.importc, nodecl, final.} = object
|
||||||
len, space: int
|
len, space: int
|
||||||
|
|
||||||
PGenericSeq {.importc, nodecl.} = ptr TGenericSeq
|
PGenericSeq {.importc, nodecl.} = ptr TGenericSeq
|
||||||
|
|
@ -1179,6 +1236,11 @@ proc getCurrentExceptionMsg(): string =
|
||||||
when defined(endb):
|
when defined(endb):
|
||||||
include debugger
|
include debugger
|
||||||
{.pop.} # stacktrace
|
{.pop.} # stacktrace
|
||||||
{.pop.} # checks
|
|
||||||
|
|
||||||
|
else:
|
||||||
|
include ecmasys
|
||||||
|
|
||||||
|
include macros
|
||||||
|
|
||||||
|
{.pop.} # checks
|
||||||
{.pop.} # hints
|
{.pop.} # hints
|
||||||
|
|
|
||||||
118
lib/times.nim
118
lib/times.nim
|
|
@ -1,7 +1,7 @@
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
# Nimrod's Runtime Library
|
# Nimrod's Runtime Library
|
||||||
# (c) Copyright 2006 Andreas Rumpf
|
# (c) Copyright 2008 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.
|
||||||
|
|
@ -9,6 +9,7 @@
|
||||||
|
|
||||||
|
|
||||||
## This module contains routines and types for dealing with time.
|
## This module contains routines and types for dealing with time.
|
||||||
|
## This module is available for the ECMAScript target.
|
||||||
|
|
||||||
{.push debugger:off .} # the user does not want to trace a part
|
{.push debugger:off .} # the user does not want to trace a part
|
||||||
# of the standard library!
|
# of the standard library!
|
||||||
|
|
@ -22,9 +23,49 @@ type
|
||||||
TWeekDay* = enum ## represents a weekday
|
TWeekDay* = enum ## represents a weekday
|
||||||
dMon, dTue, dWed, dThu, dFri, dSat, dSun
|
dMon, dTue, dWed, dThu, dFri, dSat, dSun
|
||||||
|
|
||||||
TTime* {.importc: "time_t".} = record ## abstract type that represents a time
|
TTime* {.importc: "time_t", final.} = object ## abstract type that
|
||||||
|
## represents a time
|
||||||
|
when defined(ECMAScript):
|
||||||
|
getDay: proc (): int
|
||||||
|
getFullYear: proc (): int
|
||||||
|
getHours: proc (): int
|
||||||
|
getMilliseconds: proc (): int
|
||||||
|
getMinutes: proc (): int
|
||||||
|
getMonth: proc (): int
|
||||||
|
getSeconds: proc (): int
|
||||||
|
getTime: proc (): int
|
||||||
|
getTimezoneOffset: proc (): int
|
||||||
|
getUTCDate: proc (): int
|
||||||
|
getUTCFullYear: proc (): int
|
||||||
|
getUTCHours: proc (): int
|
||||||
|
getUTCMilliseconds: proc (): int
|
||||||
|
getUTCMinutes: proc (): int
|
||||||
|
getUTCMonth: proc (): int
|
||||||
|
getUTCSeconds: proc (): int
|
||||||
|
getYear: proc (): int
|
||||||
|
parse: proc (s: cstring): TTime
|
||||||
|
setDate: proc (x: int)
|
||||||
|
setFullYear: proc (x: int)
|
||||||
|
setHours: proc (x: int)
|
||||||
|
setMilliseconds: proc (x: int)
|
||||||
|
setMinutes: proc (x: int)
|
||||||
|
setMonth: proc (x: int)
|
||||||
|
setSeconds: proc (x: int)
|
||||||
|
setTime: proc (x: int)
|
||||||
|
setUTCDate: proc (x: int)
|
||||||
|
setUTCFullYear: proc (x: int)
|
||||||
|
setUTCHours: proc (x: int)
|
||||||
|
setUTCMilliseconds: proc (x: int)
|
||||||
|
setUTCMinutes: proc (x: int)
|
||||||
|
setUTCMonth: proc (x: int)
|
||||||
|
setUTCSeconds: proc (x: int)
|
||||||
|
setYear: proc (x: int)
|
||||||
|
toGMTString: proc (): cstring
|
||||||
|
toLocaleString: proc (): cstring
|
||||||
|
UTC: proc (): int
|
||||||
|
|
||||||
TTimeInfo* = record ## represents a time in different parts
|
|
||||||
|
TTimeInfo* = object of TObject ## represents a time in different parts
|
||||||
second*: range[0..61] ## The number of seconds after the minute,
|
second*: range[0..61] ## The number of seconds after the minute,
|
||||||
## normally in the range 0 to 59, but can
|
## normally in the range 0 to 59, but can
|
||||||
## be up to 61 to allow for leap seconds.
|
## be up to 61 to allow for leap seconds.
|
||||||
|
|
@ -38,6 +79,7 @@ type
|
||||||
weekday*: TWeekDay ## The current day of the week.
|
weekday*: TWeekDay ## The current day of the week.
|
||||||
yearday*: range[0..365] ## The number of days since January 1,
|
yearday*: range[0..365] ## The number of days since January 1,
|
||||||
## in the range 0 to 365.
|
## in the range 0 to 365.
|
||||||
|
## Always 0 if the target is ECMAScript.
|
||||||
|
|
||||||
proc getTime*(): TTime ## gets the current calendar time
|
proc getTime*(): TTime ## gets the current calendar time
|
||||||
proc getLocalTime*(t: TTime): TTimeInfo
|
proc getLocalTime*(t: TTime): TTimeInfo
|
||||||
|
|
@ -54,7 +96,7 @@ proc TimeInfoToTime*(timeInfo: TTimeInfo): TTime
|
||||||
## them from the other information in the broken-down time structure.
|
## them from the other information in the broken-down time structure.
|
||||||
|
|
||||||
proc `$` *(timeInfo: TTimeInfo): string
|
proc `$` *(timeInfo: TTimeInfo): string
|
||||||
## converts a `TTimeInfo` record to a
|
## converts a `TTimeInfo` object to a
|
||||||
## string representation.
|
## string representation.
|
||||||
proc `$` *(time: TTime): string
|
proc `$` *(time: TTime): string
|
||||||
## converts a calendar time to a
|
## converts a calendar time to a
|
||||||
|
|
@ -72,11 +114,12 @@ proc `-` *(a, b: TTime): int64
|
||||||
proc getStartMilsecs*(): int
|
proc getStartMilsecs*(): int
|
||||||
## get the miliseconds from the start of the program
|
## get the miliseconds from the start of the program
|
||||||
|
|
||||||
#implementation
|
|
||||||
|
when not defined(ECMAScript):
|
||||||
|
|
||||||
# C wrapper:
|
# C wrapper:
|
||||||
type
|
type
|
||||||
structTM {.importc: "struct tm".} = record
|
structTM {.importc: "struct tm", final.} = object
|
||||||
second {.importc: "tm_sec".},
|
second {.importc: "tm_sec".},
|
||||||
minute {.importc: "tm_min".},
|
minute {.importc: "tm_min".},
|
||||||
hour {.importc: "tm_hour".},
|
hour {.importc: "tm_hour".},
|
||||||
|
|
@ -159,6 +202,62 @@ proc TimeInfoToTime(timeInfo: TTimeInfo): TTime =
|
||||||
# because the header of mktime is broken in my version of libc
|
# because the header of mktime is broken in my version of libc
|
||||||
return mktime(timeInfoToTM(cTimeInfo))
|
return mktime(timeInfoToTM(cTimeInfo))
|
||||||
|
|
||||||
|
proc `$`(timeInfo: TTimeInfo): string =
|
||||||
|
return $asctime(timeInfoToTM(timeInfo))
|
||||||
|
|
||||||
|
proc `$`(time: TTime): string =
|
||||||
|
var a = time
|
||||||
|
return $ctime(addr(a))
|
||||||
|
|
||||||
|
else:
|
||||||
|
proc getTime(): TTime {.importc: "new Date", nodecl.}
|
||||||
|
|
||||||
|
const
|
||||||
|
weekDays: array [0..6, TWeekDay] = [
|
||||||
|
dSun, dMon, dTue, dWed, dThu, dFri, dSat]
|
||||||
|
|
||||||
|
proc getLocalTime(t: TTime): TTimeInfo =
|
||||||
|
result.second = t.getSeconds()
|
||||||
|
result.minute = t.getMinutes()
|
||||||
|
result.hour = t.getHours()
|
||||||
|
result.monthday = t.getDate()
|
||||||
|
result.month = TMonth(t.getMonth())
|
||||||
|
result.year = t.getFullYear()
|
||||||
|
result.weekday = weekDays[t.getDay()]
|
||||||
|
result.yearday = 0
|
||||||
|
|
||||||
|
proc getGMTime(t: TTime): TTimeInfo =
|
||||||
|
result.second = t.getUTCSeconds()
|
||||||
|
result.minute = t.getUTCMinutes()
|
||||||
|
result.hour = t.getUTCHours()
|
||||||
|
result.monthday = t.getUTCDate()
|
||||||
|
result.month = TMonth(t.getUTCMonth())
|
||||||
|
result.year = t.getUTCFullYear()
|
||||||
|
result.weekday = weekDays[t.getDay()]
|
||||||
|
result.yearday = 0
|
||||||
|
|
||||||
|
proc TimeInfoToTime*(timeInfo: TTimeInfo): TTime =
|
||||||
|
result = getTime()
|
||||||
|
result.setSeconds(timeInfo.second)
|
||||||
|
result.setMinutes(timeInfo.minute)
|
||||||
|
result.setHours(timeInfo.hour)
|
||||||
|
result.setMonth(ord(timeInfo.month))
|
||||||
|
result.setFullYear(timeInfo.year)
|
||||||
|
result.setDate(timeInfo.monthday)
|
||||||
|
|
||||||
|
proc `$`(timeInfo: TTimeInfo): string = return $(TimeInfoToTIme(timeInfo))
|
||||||
|
proc `$`(time: TTime): string = $time.toLocaleString()
|
||||||
|
|
||||||
|
proc `-` (a, b: TTime): int64 =
|
||||||
|
return a.getTime() - b.getTime()
|
||||||
|
|
||||||
|
var
|
||||||
|
startMilsecs = getTime()
|
||||||
|
|
||||||
|
proc getStartMilsecs(): int =
|
||||||
|
## get the miliseconds from the start of the program
|
||||||
|
return int(getTime() - startMilsecs)
|
||||||
|
|
||||||
proc getDateStr(): string =
|
proc getDateStr(): string =
|
||||||
var ti = getLocalTime(getTime())
|
var ti = getLocalTime(getTime())
|
||||||
result = $ti.year & "-" & intToStr(ord(ti.month)+1, 2) &
|
result = $ti.year & "-" & intToStr(ord(ti.month)+1, 2) &
|
||||||
|
|
@ -169,11 +268,4 @@ proc getClockStr(): string =
|
||||||
result = intToStr(ti.hour, 2) & ':' & intToStr(ti.minute, 2) &
|
result = intToStr(ti.hour, 2) & ':' & intToStr(ti.minute, 2) &
|
||||||
':' & intToStr(ti.second, 2)
|
':' & intToStr(ti.second, 2)
|
||||||
|
|
||||||
proc `$`(timeInfo: TTimeInfo): string =
|
|
||||||
return $asctime(timeInfoToTM(timeInfo))
|
|
||||||
|
|
||||||
proc `$`(time: TTime): string =
|
|
||||||
var a = time
|
|
||||||
return $ctime(addr(a))
|
|
||||||
|
|
||||||
{.pop.}
|
{.pop.}
|
||||||
|
|
|
||||||
221
lib/typeinfo.nim
221
lib/typeinfo.nim
|
|
@ -1,221 +0,0 @@
|
||||||
#
|
|
||||||
#
|
|
||||||
# Nimrod's Runtime Library
|
|
||||||
# (c) Copyright 2006 Andreas Rumpf
|
|
||||||
#
|
|
||||||
# See the file "copying.txt", included in this
|
|
||||||
# distribution, for details about the copyright.
|
|
||||||
#
|
|
||||||
|
|
||||||
# type-info module for Nimrod
|
|
||||||
|
|
||||||
include hti
|
|
||||||
|
|
||||||
proc typeid(x: any): PNimType
|
|
||||||
|
|
||||||
type
|
|
||||||
Variant = opaque record
|
|
||||||
# contains the address and a typeinfo
|
|
||||||
a: pointer # an address
|
|
||||||
k: TNimTypeKind
|
|
||||||
|
|
||||||
# conversions to any and from any are inserted by the compiler!
|
|
||||||
# x.attr is supported, as well as x[]!
|
|
||||||
# here is a special iterator for variants:
|
|
||||||
iterator fields(x: variant): (fieldname: string, value: variant) =
|
|
||||||
proc setField(structure: variant, fieldname: string, value: variant)
|
|
||||||
proc getField(structure: variant, fieldname: string)
|
|
||||||
|
|
||||||
# any is implemented as a pair (val: pointer, info: PTypeInfo)
|
|
||||||
# val is for:
|
|
||||||
# an array - its address
|
|
||||||
# a record - its address
|
|
||||||
# an object - its address
|
|
||||||
# a string - the address of the pointer to the string data
|
|
||||||
# a sequence - the address of the pointer to the sequence data
|
|
||||||
# a float - the address of a memory location where the float is stored
|
|
||||||
# this is a given address; storage comes from compiler or is
|
|
||||||
# already there (in a container)
|
|
||||||
# an int - the address of a memory location where the int is stored
|
|
||||||
# storage comes from compiler or is
|
|
||||||
# already there (in a container)
|
|
||||||
# a cstring - the address of an address of an array of chars
|
|
||||||
# a ref - the address of the ref! (not the ref itself!)
|
|
||||||
|
|
||||||
# But this does not work too well...
|
|
||||||
# Better: any is a ref to Object; than we define intObj, floatObj,
|
|
||||||
# etc.; for strings this not needed as they already fit into the
|
|
||||||
# scheme!
|
|
||||||
#
|
|
||||||
|
|
||||||
type
|
|
||||||
TAnyImpl {.exportc: "TAnyImpl".} = record
|
|
||||||
typ {.exportc: "info".}: PNimType
|
|
||||||
val {.exportc: "val".}: pointer
|
|
||||||
|
|
||||||
proc
|
|
||||||
typeKind(p: PNimType): TTypeKind {.inline.}
|
|
||||||
|
|
||||||
getAnyLength(x: any): int
|
|
||||||
|
|
||||||
isContainer(x: any): bool
|
|
||||||
|
|
||||||
writeAny(container: any, index: int, val: any)
|
|
||||||
readAny(container: any, index: int): any
|
|
||||||
|
|
||||||
writeAny(container: any, name: string, val: any)
|
|
||||||
readAny(container: any, name: string): any
|
|
||||||
|
|
||||||
getAttr(container: any, index: int, out name: string, out val: any)
|
|
||||||
|
|
||||||
getEnumStrings(enumeration: any): sequence of string
|
|
||||||
|
|
||||||
anyToInt(x: any): biggestint
|
|
||||||
anyToFloat(x: any): biggestfloat
|
|
||||||
anyToString(x: any): string
|
|
||||||
anyToChar(x: any): char
|
|
||||||
anyToBool(x: any): bool
|
|
||||||
#anyToT{T}(x: any, out result: T)
|
|
||||||
|
|
||||||
# etc...
|
|
||||||
|
|
||||||
#write(a: array of any) # also possible!
|
|
||||||
|
|
||||||
#generic proc
|
|
||||||
# deepCopy{T}(x: T): T
|
|
||||||
|
|
||||||
import
|
|
||||||
strutils
|
|
||||||
|
|
||||||
proc anyToImpl(a: any): TAnyImpl {.inline.} =
|
|
||||||
result = cast{TAnyImpl}(a)
|
|
||||||
|
|
||||||
proc typeKind(p: PNimType): TTypeKind =
|
|
||||||
result = p.typeKind
|
|
||||||
|
|
||||||
type
|
|
||||||
Pint = untraced ref int
|
|
||||||
Pint8 = untraced ref int8
|
|
||||||
Pint16 = untraced ref int16
|
|
||||||
Pint32 = untraced ref int32
|
|
||||||
Pint64 = untraced ref int64
|
|
||||||
Puint = untraced ref uint
|
|
||||||
Puint8 = untraced ref uint8
|
|
||||||
Puint16 = untraced ref uint16
|
|
||||||
Puint32 = untraced ref uint32
|
|
||||||
Puint64 = untraced ref uint64
|
|
||||||
Pfloat = untraced ref float
|
|
||||||
Pfloat32 = untraced ref float32
|
|
||||||
Pfloat64 = untraced ref float64
|
|
||||||
Pstring = untraced ref string
|
|
||||||
Pbool = untraced ref bool
|
|
||||||
Pchar = untraced ref char
|
|
||||||
|
|
||||||
proc anyToInt(x: any): biggestint =
|
|
||||||
var impl = anyToImpl(x)
|
|
||||||
case impl.typ.typeKind
|
|
||||||
of tyInt, tyEnum: result = cast{pint}(x.val)^
|
|
||||||
of tySInt8: result = cast{pint8}(x.val)^
|
|
||||||
of tySInt16: result = cast{pint16}(x.val)^
|
|
||||||
of tySInt32: result = cast{pint32}(x.val)^
|
|
||||||
of tySInt64: result = cast{pint64}(x.val)^
|
|
||||||
of tyUInt: result = cast{puint}(x.val)^
|
|
||||||
of tyUInt8: result = cast{puint8}(x.val)^
|
|
||||||
of tyUInt16: result = cast{puint16}(x.val)^
|
|
||||||
of tyUInt32: result = cast{puint32}(x.val)^
|
|
||||||
of tyUInt64: result = cast{puint64}(x.val)^
|
|
||||||
else: raise EConvertError
|
|
||||||
|
|
||||||
proc anyToFloat(x: any): biggestfloat =
|
|
||||||
var impl = anyToImpl(x)
|
|
||||||
case impl.typ.typeKind
|
|
||||||
of tyReal: result = cast{pfloat}(x.val)^
|
|
||||||
of tyReal32: result = cast{pfloat32}(x.val)^
|
|
||||||
of tyReal64: result = cast{pfloat64}(x.val)^
|
|
||||||
# of tyReal128:
|
|
||||||
else: raise EConvertError
|
|
||||||
|
|
||||||
proc anyToString(x: any): string =
|
|
||||||
var impl = anyToImpl(x)
|
|
||||||
case impl.typ.typeKind
|
|
||||||
of tyString: result = cast{pstring}(x.val)^
|
|
||||||
else: raise EConvertError
|
|
||||||
|
|
||||||
proc anyToChar(x: any): char =
|
|
||||||
var impl = anyToImpl(x)
|
|
||||||
case impl.typ.typeKind
|
|
||||||
of tyChar: result = cast{pchar}(x.val)^
|
|
||||||
else: raise EConvertError
|
|
||||||
|
|
||||||
proc anyToBool(x: any): bool =
|
|
||||||
var impl = anyToImpl(x)
|
|
||||||
case impl.typ.typeKind
|
|
||||||
of tyBool: result = cast{pbool}(x.val)^
|
|
||||||
else: raise EConvertError
|
|
||||||
|
|
||||||
proc getAnyLength(x: any): int =
|
|
||||||
result = anyToImpl(x).typ.len
|
|
||||||
|
|
||||||
const
|
|
||||||
ContainerSet = {tyArray, tyRecord, tyObject, tyOpenArray, tySequence, tyTable}
|
|
||||||
|
|
||||||
proc isContainer(x: any): bool =
|
|
||||||
result = anyToImpl(x).typ.typeKind in ContainerSet
|
|
||||||
|
|
||||||
proc strcmp(a, b: cstring): int {.external: "strcmp", nodecl.}
|
|
||||||
|
|
||||||
proc strToIndex(info: PTypeInfo, str: string): int =
|
|
||||||
for i in 0..typ.len-1:
|
|
||||||
if strcmp(info.slots[i].name, str) == 0:
|
|
||||||
return i
|
|
||||||
raise EConvertError
|
|
||||||
|
|
||||||
proc writeAny(container: any, index: int, val: any) =
|
|
||||||
var x = anyToImpl(container)
|
|
||||||
if index >= 0 and index < container.len:
|
|
||||||
case x.typ.typeKind
|
|
||||||
of tySequence:
|
|
||||||
var u = cast{TAddress}(x.val)
|
|
||||||
genericAssignAux(cast{pointer}(u) +% x.typ.slots[index].offset +%
|
|
||||||
GenericSeqSize,
|
|
||||||
anyToImpl(val).val, u.typ.baseType)
|
|
||||||
of tyArray:
|
|
||||||
of tyRecord, tyObject:
|
|
||||||
else: raise EConvertError
|
|
||||||
else:
|
|
||||||
raise EIndexError
|
|
||||||
|
|
||||||
|
|
||||||
proc readAny(container: any, index: int): any =
|
|
||||||
var x = anyToImpl(container)
|
|
||||||
if x.typ.typeKind in ContainerSet:
|
|
||||||
if index >= 0 and index < container.len:
|
|
||||||
# XXX
|
|
||||||
|
|
||||||
else:
|
|
||||||
raise EIndexError
|
|
||||||
else:
|
|
||||||
raise EConvertError
|
|
||||||
|
|
||||||
proc writeAny(container: any, name: string, val: any) =
|
|
||||||
result = writeAny(container, strToIndex(anyToImpl(container).typ), val)
|
|
||||||
|
|
||||||
proc readAny(container: any, name: string): any =
|
|
||||||
result = readAny(container, strToIndex(anyToImpl(container).typ))
|
|
||||||
|
|
||||||
proc getAttr(container: any, index: int, out name: string, out val: any) =
|
|
||||||
var x = anyToImpl(container)
|
|
||||||
if x.typ.typeKind in ContainerSet:
|
|
||||||
val = readAny(container, index)
|
|
||||||
name = $x.typ.slots[index].name
|
|
||||||
else:
|
|
||||||
raise EConvertError
|
|
||||||
|
|
||||||
proc getEnumStrings(enumeration: any): sequence of string =
|
|
||||||
result = []
|
|
||||||
var x = anyToImpl(enumeration)
|
|
||||||
if x.typ.typekind == tyEnum:
|
|
||||||
for i in 0 .. x.typ.len-1:
|
|
||||||
result &= $x.typ.slots[i].name
|
|
||||||
else:
|
|
||||||
raise EConvertError
|
|
||||||
|
|
@ -980,7 +980,7 @@ const
|
||||||
#/////////////////////////////////////////////////////////
|
#/////////////////////////////////////////////////////////
|
||||||
|
|
||||||
type
|
type
|
||||||
mmtime* = record
|
mmtime* {.final.} = object
|
||||||
wType*: UINT
|
wType*: UINT
|
||||||
hour*, min*, sec*, frame*, fps*, dummy*: int8
|
hour*, min*, sec*, frame*, fps*, dummy*: int8
|
||||||
pad*: array[0..1, int8]
|
pad*: array[0..1, int8]
|
||||||
|
|
@ -990,7 +990,7 @@ type
|
||||||
LPMMTIME* = ptr mmtime
|
LPMMTIME* = ptr mmtime
|
||||||
PWAVEHDR* = ptr wavehdr
|
PWAVEHDR* = ptr wavehdr
|
||||||
TMMTime* = mmtime
|
TMMTime* = mmtime
|
||||||
wavehdr* = record
|
wavehdr* {.final.} = object
|
||||||
lpData*: cstring
|
lpData*: cstring
|
||||||
dwBufferLength*: DWORD
|
dwBufferLength*: DWORD
|
||||||
dwBytesRecorded*: DWORD
|
dwBytesRecorded*: DWORD
|
||||||
|
|
@ -1003,7 +1003,7 @@ type
|
||||||
TWAVEHDR* = WAVEHDR
|
TWAVEHDR* = WAVEHDR
|
||||||
NPWAVEHDR* = ptr wavehdr
|
NPWAVEHDR* = ptr wavehdr
|
||||||
LPWAVEHDR* = ptr wavehdr
|
LPWAVEHDR* = ptr wavehdr
|
||||||
WAVEOUTCAPSA* = record
|
WAVEOUTCAPSA* {.final.} = object
|
||||||
wMid*: int16
|
wMid*: int16
|
||||||
wPid*: int16
|
wPid*: int16
|
||||||
vDriverVersion*: MMVERSION
|
vDriverVersion*: MMVERSION
|
||||||
|
|
@ -1017,7 +1017,7 @@ type
|
||||||
PWAVEOUTCAPSA* = ptr WAVEOUTCAPSA
|
PWAVEOUTCAPSA* = ptr WAVEOUTCAPSA
|
||||||
NPWAVEOUTCAPSA* = ptr WAVEOUTCAPSA
|
NPWAVEOUTCAPSA* = ptr WAVEOUTCAPSA
|
||||||
LPWAVEOUTCAPSA* = ptr WAVEOUTCAPSA
|
LPWAVEOUTCAPSA* = ptr WAVEOUTCAPSA
|
||||||
WAVEOUTCAPSW* = record
|
WAVEOUTCAPSW* {.final.} = object
|
||||||
wMid*: int16
|
wMid*: int16
|
||||||
wPid*: int16
|
wPid*: int16
|
||||||
vDriverVersion*: MMVERSION
|
vDriverVersion*: MMVERSION
|
||||||
|
|
@ -1046,7 +1046,7 @@ else:
|
||||||
LPWAVEOUTCAPS* = LPWAVEOUTCAPSA
|
LPWAVEOUTCAPS* = LPWAVEOUTCAPSA
|
||||||
type
|
type
|
||||||
TWAVEOUTCAPS* = WAVEOUTCAPS
|
TWAVEOUTCAPS* = WAVEOUTCAPS
|
||||||
WAVEINCAPSA* = record
|
WAVEINCAPSA* {.final.} = object
|
||||||
wMid*: int16
|
wMid*: int16
|
||||||
wPid*: int16
|
wPid*: int16
|
||||||
vDriverVersion*: MMVERSION
|
vDriverVersion*: MMVERSION
|
||||||
|
|
@ -1059,7 +1059,7 @@ type
|
||||||
NPWAVEINCAPSA* = ptr WAVEINCAPSA
|
NPWAVEINCAPSA* = ptr WAVEINCAPSA
|
||||||
LPWAVEINCAPSA* = ptr WAVEINCAPSA
|
LPWAVEINCAPSA* = ptr WAVEINCAPSA
|
||||||
TWAVEINCAPSA* = WAVEINCAPSA
|
TWAVEINCAPSA* = WAVEINCAPSA
|
||||||
WAVEINCAPSW* = record
|
WAVEINCAPSW* {.final.} = object
|
||||||
wMid*: int16
|
wMid*: int16
|
||||||
wPid*: int16
|
wPid*: int16
|
||||||
vDriverVersion*: MMVERSION
|
vDriverVersion*: MMVERSION
|
||||||
|
|
@ -1087,7 +1087,7 @@ else:
|
||||||
LPWAVEINCAPS* = LPWAVEINCAPSA
|
LPWAVEINCAPS* = LPWAVEINCAPSA
|
||||||
type
|
type
|
||||||
TWAVEINCAPS* = WAVEINCAPS
|
TWAVEINCAPS* = WAVEINCAPS
|
||||||
waveformat* = record
|
waveformat* {.final.} = object
|
||||||
wFormatTag*: int16
|
wFormatTag*: int16
|
||||||
nChannels*: int16
|
nChannels*: int16
|
||||||
nSamplesPerSec*: DWORD
|
nSamplesPerSec*: DWORD
|
||||||
|
|
@ -1103,7 +1103,7 @@ const
|
||||||
WAVE_FORMAT_PCM* = 1
|
WAVE_FORMAT_PCM* = 1
|
||||||
|
|
||||||
type
|
type
|
||||||
pcmwaveformat* = record
|
pcmwaveformat* {.final.} = object
|
||||||
wf*: WAVEFORMAT
|
wf*: WAVEFORMAT
|
||||||
wBitsPerSample*: int16
|
wBitsPerSample*: int16
|
||||||
|
|
||||||
|
|
@ -1111,7 +1111,7 @@ type
|
||||||
NPPCMWAVEFORMAT* = ptr pcmwaveformat
|
NPPCMWAVEFORMAT* = ptr pcmwaveformat
|
||||||
LPPCMWAVEFORMAT* = ptr pcmwaveformat
|
LPPCMWAVEFORMAT* = ptr pcmwaveformat
|
||||||
TPCMWAVEFORMAT* = PCMWAVEFORMAT
|
TPCMWAVEFORMAT* = PCMWAVEFORMAT
|
||||||
WAVEFORMATEX* = record
|
WAVEFORMATEX* {.final.} = object
|
||||||
wFormatTag*: int16
|
wFormatTag*: int16
|
||||||
nChannels*: int16
|
nChannels*: int16
|
||||||
nSamplesPerSec*: DWORD
|
nSamplesPerSec*: DWORD
|
||||||
|
|
@ -1143,7 +1143,7 @@ type
|
||||||
LPPATCHARRAY* = ptr int16
|
LPPATCHARRAY* = ptr int16
|
||||||
KEYARRAY* = array[0..Pred(MIDIPATCHSIZE), int16]
|
KEYARRAY* = array[0..Pred(MIDIPATCHSIZE), int16]
|
||||||
LPKEYARRAY* = ptr int16
|
LPKEYARRAY* = ptr int16
|
||||||
MIDIOUTCAPSA* = record
|
MIDIOUTCAPSA* {.final.} = object
|
||||||
wMid*: int16
|
wMid*: int16
|
||||||
wPid*: int16
|
wPid*: int16
|
||||||
vDriverVersion*: MMVERSION
|
vDriverVersion*: MMVERSION
|
||||||
|
|
@ -1158,7 +1158,7 @@ type
|
||||||
NPMIDIOUTCAPSA* = ptr MIDIOUTCAPSA
|
NPMIDIOUTCAPSA* = ptr MIDIOUTCAPSA
|
||||||
LPMIDIOUTCAPSA* = ptr MIDIOUTCAPSA
|
LPMIDIOUTCAPSA* = ptr MIDIOUTCAPSA
|
||||||
TMIDIOUTCAPSA* = MIDIOUTCAPSA
|
TMIDIOUTCAPSA* = MIDIOUTCAPSA
|
||||||
MIDIOUTCAPSW* = record
|
MIDIOUTCAPSW* {.final.} = object
|
||||||
wMid*: int16
|
wMid*: int16
|
||||||
wPid*: int16
|
wPid*: int16
|
||||||
vDriverVersion*: MMVERSION
|
vDriverVersion*: MMVERSION
|
||||||
|
|
@ -1173,7 +1173,7 @@ type
|
||||||
NPMIDIOUTCAPSW* = ptr MIDIOUTCAPSW
|
NPMIDIOUTCAPSW* = ptr MIDIOUTCAPSW
|
||||||
LPMIDIOUTCAPSW* = ptr MIDIOUTCAPSW
|
LPMIDIOUTCAPSW* = ptr MIDIOUTCAPSW
|
||||||
TMIDIOUTCAPSW* = MIDIOUTCAPSW
|
TMIDIOUTCAPSW* = MIDIOUTCAPSW
|
||||||
MIDIINCAPSA* = record
|
MIDIINCAPSA* {.final.} = object
|
||||||
wMid*: int16
|
wMid*: int16
|
||||||
wPid*: int16
|
wPid*: int16
|
||||||
vDriverVersion*: MMVERSION
|
vDriverVersion*: MMVERSION
|
||||||
|
|
@ -1184,7 +1184,7 @@ type
|
||||||
NPMIDIINCAPSA* = ptr MIDIINCAPSA
|
NPMIDIINCAPSA* = ptr MIDIINCAPSA
|
||||||
LPMIDIINCAPSA* = ptr MIDIINCAPSA
|
LPMIDIINCAPSA* = ptr MIDIINCAPSA
|
||||||
TMIDIINCAPSA* = MIDIINCAPSA
|
TMIDIINCAPSA* = MIDIINCAPSA
|
||||||
MIDIINCAPSW* = record
|
MIDIINCAPSW* {.final.} = object
|
||||||
wMid*: int16
|
wMid*: int16
|
||||||
wPid*: int16
|
wPid*: int16
|
||||||
vDriverVersion*: MMVERSION
|
vDriverVersion*: MMVERSION
|
||||||
|
|
@ -1219,7 +1219,7 @@ else:
|
||||||
type
|
type
|
||||||
TMIDIINCAPS* = MIDIINCAPS
|
TMIDIINCAPS* = MIDIINCAPS
|
||||||
PMIDIHDR* = ptr midihdr
|
PMIDIHDR* = ptr midihdr
|
||||||
midihdr* = record
|
midihdr* {.final.} = object
|
||||||
lpData*: cstring
|
lpData*: cstring
|
||||||
dwBufferLength*: DWORD
|
dwBufferLength*: DWORD
|
||||||
dwBytesRecorded*: DWORD
|
dwBytesRecorded*: DWORD
|
||||||
|
|
@ -1233,30 +1233,30 @@ type
|
||||||
NPMIDIHDR* = ptr midihdr
|
NPMIDIHDR* = ptr midihdr
|
||||||
LPMIDIHDR* = ptr midihdr
|
LPMIDIHDR* = ptr midihdr
|
||||||
TMIDIHDR* = MIDIHDR
|
TMIDIHDR* = MIDIHDR
|
||||||
midievent* = record
|
midievent* {.final.} = object
|
||||||
dwDeltaTime*: DWORD
|
dwDeltaTime*: DWORD
|
||||||
dwStreamID*: DWORD
|
dwStreamID*: DWORD
|
||||||
dwEvent*: DWORD
|
dwEvent*: DWORD
|
||||||
dwParms*: array[0..Pred(1), DWORD]
|
dwParms*: array[0..Pred(1), DWORD]
|
||||||
|
|
||||||
TMIDIEVENT* = MIDIEVENT
|
TMIDIEVENT* = MIDIEVENT
|
||||||
midistrmbuffver* = record
|
midistrmbuffver* {.final.} = object
|
||||||
dwVersion*: DWORD
|
dwVersion*: DWORD
|
||||||
dwMid*: DWORD
|
dwMid*: DWORD
|
||||||
dwOEMVersion*: DWORD
|
dwOEMVersion*: DWORD
|
||||||
|
|
||||||
TMIDISTRMBUFFVER* = MIDISTRMBUFFVER
|
TMIDISTRMBUFFVER* = MIDISTRMBUFFVER
|
||||||
Tmidiproptimediv* = record
|
Tmidiproptimediv* {.final.} = object
|
||||||
cbStruct*: DWORD
|
cbStruct*: DWORD
|
||||||
dwTimeDiv*: DWORD
|
dwTimeDiv*: DWORD
|
||||||
|
|
||||||
LPMIDIPROPTIMEDIV* = ptr Tmidiproptimediv
|
LPMIDIPROPTIMEDIV* = ptr Tmidiproptimediv
|
||||||
Tmidiproptempo* = record
|
Tmidiproptempo* {.final.} = object
|
||||||
cbStruct*: DWORD
|
cbStruct*: DWORD
|
||||||
dwTempo*: DWORD
|
dwTempo*: DWORD
|
||||||
|
|
||||||
LPMIDIPROPTEMPO* = ptr Tmidiproptempo
|
LPMIDIPROPTEMPO* = ptr Tmidiproptempo
|
||||||
AUXCAPSA* = record
|
AUXCAPSA* {.final.} = object
|
||||||
wMid*: int16
|
wMid*: int16
|
||||||
wPid*: int16
|
wPid*: int16
|
||||||
vDriverVersion*: MMVERSION
|
vDriverVersion*: MMVERSION
|
||||||
|
|
@ -1269,7 +1269,7 @@ type
|
||||||
NPAUXCAPSA* = ptr AUXCAPSA
|
NPAUXCAPSA* = ptr AUXCAPSA
|
||||||
LPAUXCAPSA* = ptr AUXCAPSA
|
LPAUXCAPSA* = ptr AUXCAPSA
|
||||||
TAUXCAPSA* = AUXCAPSA
|
TAUXCAPSA* = AUXCAPSA
|
||||||
AUXCAPSW* = record
|
AUXCAPSW* {.final.} = object
|
||||||
wMid*: int16
|
wMid*: int16
|
||||||
wPid*: int16
|
wPid*: int16
|
||||||
vDriverVersion*: MMVERSION
|
vDriverVersion*: MMVERSION
|
||||||
|
|
@ -1305,7 +1305,7 @@ type
|
||||||
proc mixerGetNumDevs*(): UINT{.stdcall, dynlib: "winmm.dll",
|
proc mixerGetNumDevs*(): UINT{.stdcall, dynlib: "winmm.dll",
|
||||||
importc: "mixerGetNumDevs".}
|
importc: "mixerGetNumDevs".}
|
||||||
type
|
type
|
||||||
MIXERCAPSA* = record
|
MIXERCAPSA* {.final.} = object
|
||||||
wMid*: int16
|
wMid*: int16
|
||||||
wPid*: int16
|
wPid*: int16
|
||||||
vDriverVersion*: MMVERSION
|
vDriverVersion*: MMVERSION
|
||||||
|
|
@ -1316,7 +1316,7 @@ type
|
||||||
PMIXERCAPSA* = ptr MIXERCAPSA
|
PMIXERCAPSA* = ptr MIXERCAPSA
|
||||||
LPMIXERCAPSA* = ptr MIXERCAPSA
|
LPMIXERCAPSA* = ptr MIXERCAPSA
|
||||||
TMIXERCAPSA* = MIXERCAPSA
|
TMIXERCAPSA* = MIXERCAPSA
|
||||||
MIXERCAPSW* = record
|
MIXERCAPSW* {.final.} = object
|
||||||
wMid*: int16
|
wMid*: int16
|
||||||
wPid*: int16
|
wPid*: int16
|
||||||
vDriverVersion*: MMVERSION
|
vDriverVersion*: MMVERSION
|
||||||
|
|
@ -1340,7 +1340,7 @@ else:
|
||||||
LPMIXERCAPS* = LPMIXERCAPSA
|
LPMIXERCAPS* = LPMIXERCAPSA
|
||||||
type
|
type
|
||||||
TMIXERCAPS* = MIXERCAPS
|
TMIXERCAPS* = MIXERCAPS
|
||||||
MIXERLINEA* = record
|
MIXERLINEA* {.final.} = object
|
||||||
cbStruct*: DWORD
|
cbStruct*: DWORD
|
||||||
dwDestination*: DWORD
|
dwDestination*: DWORD
|
||||||
dwSource*: DWORD
|
dwSource*: DWORD
|
||||||
|
|
@ -1361,7 +1361,7 @@ type
|
||||||
PMIXERLINEA* = ptr MIXERLINEA
|
PMIXERLINEA* = ptr MIXERLINEA
|
||||||
LPMIXERLINEA* = ptr MIXERLINEA
|
LPMIXERLINEA* = ptr MIXERLINEA
|
||||||
TMIXERLINEA* = MIXERLINEA
|
TMIXERLINEA* = MIXERLINEA
|
||||||
MIXERLINEW* = record
|
MIXERLINEW* {.final.} = object
|
||||||
cbStruct*: DWORD
|
cbStruct*: DWORD
|
||||||
dwDestination*: DWORD
|
dwDestination*: DWORD
|
||||||
dwSource*: DWORD
|
dwSource*: DWORD
|
||||||
|
|
@ -1395,7 +1395,7 @@ else:
|
||||||
LPMIXERLINE* = LPMIXERLINEA
|
LPMIXERLINE* = LPMIXERLINEA
|
||||||
type
|
type
|
||||||
TMIXERLINE* = MIXERLINE
|
TMIXERLINE* = MIXERLINE
|
||||||
MIXERCONTROLA* = record
|
MIXERCONTROLA* {.final.} = object
|
||||||
cbStruct*: DWORD
|
cbStruct*: DWORD
|
||||||
dwControlID*: DWORD
|
dwControlID*: DWORD
|
||||||
dwControlType*: DWORD
|
dwControlType*: DWORD
|
||||||
|
|
@ -1411,7 +1411,7 @@ type
|
||||||
PMIXERCONTROLA* = ptr MIXERCONTROLA
|
PMIXERCONTROLA* = ptr MIXERCONTROLA
|
||||||
LPMIXERCONTROLA* = ptr MIXERCONTROLA
|
LPMIXERCONTROLA* = ptr MIXERCONTROLA
|
||||||
TMIXERCONTROLA* = MIXERCONTROLA
|
TMIXERCONTROLA* = MIXERCONTROLA
|
||||||
MIXERCONTROLW* = record
|
MIXERCONTROLW* {.final.} = object
|
||||||
cbStruct*: DWORD
|
cbStruct*: DWORD
|
||||||
dwControlID*: DWORD
|
dwControlID*: DWORD
|
||||||
dwControlType*: DWORD
|
dwControlType*: DWORD
|
||||||
|
|
@ -1440,7 +1440,7 @@ else:
|
||||||
LPMIXERCONTROL* = LPMIXERCONTROLA
|
LPMIXERCONTROL* = LPMIXERCONTROLA
|
||||||
type
|
type
|
||||||
TMIXERCONTROL* = MIXERCONTROL
|
TMIXERCONTROL* = MIXERCONTROL
|
||||||
MIXERLINECONTROLSA* = record
|
MIXERLINECONTROLSA* {.final.} = object
|
||||||
cbStruct*: DWORD
|
cbStruct*: DWORD
|
||||||
dwLineID*: DWORD
|
dwLineID*: DWORD
|
||||||
dwControlType*, cControls*, cbmxctrl*: DWORD
|
dwControlType*, cControls*, cbmxctrl*: DWORD
|
||||||
|
|
@ -1449,7 +1449,7 @@ type
|
||||||
PMIXERLINECONTROLSA* = ptr MIXERLINECONTROLSA
|
PMIXERLINECONTROLSA* = ptr MIXERLINECONTROLSA
|
||||||
LPMIXERLINECONTROLSA* = ptr MIXERLINECONTROLSA
|
LPMIXERLINECONTROLSA* = ptr MIXERLINECONTROLSA
|
||||||
TMIXERLINECONTROLSA* = MIXERLINECONTROLSA
|
TMIXERLINECONTROLSA* = MIXERLINECONTROLSA
|
||||||
MIXERLINECONTROLSW* = record
|
MIXERLINECONTROLSW* {.final.} = object
|
||||||
cbStruct*: DWORD
|
cbStruct*: DWORD
|
||||||
dwLineID*: DWORD
|
dwLineID*: DWORD
|
||||||
dwControlType*, cControls*, cbmxctrl*: DWORD
|
dwControlType*, cControls*, cbmxctrl*: DWORD
|
||||||
|
|
@ -1471,7 +1471,7 @@ else:
|
||||||
LPMIXERLINECONTROLS* = LPMIXERLINECONTROLSA
|
LPMIXERLINECONTROLS* = LPMIXERLINECONTROLSA
|
||||||
type
|
type
|
||||||
TMIXERLINECONTROLS* = MIXERLINECONTROLS
|
TMIXERLINECONTROLS* = MIXERLINECONTROLS
|
||||||
TMIXERCONTROLDETAILS* = record
|
TMIXERCONTROLDETAILS* {.final.} = object
|
||||||
cbStruct*: DWORD
|
cbStruct*: DWORD
|
||||||
dwControlID*: DWORD
|
dwControlID*: DWORD
|
||||||
cChannels*: DWORD
|
cChannels*: DWORD
|
||||||
|
|
@ -1481,7 +1481,7 @@ type
|
||||||
MIXERCONTROLDETAILS* = tMIXERCONTROLDETAILS
|
MIXERCONTROLDETAILS* = tMIXERCONTROLDETAILS
|
||||||
PMIXERCONTROLDETAILS* = ptr tMIXERCONTROLDETAILS
|
PMIXERCONTROLDETAILS* = ptr tMIXERCONTROLDETAILS
|
||||||
LPMIXERCONTROLDETAILS* = ptr tMIXERCONTROLDETAILS
|
LPMIXERCONTROLDETAILS* = ptr tMIXERCONTROLDETAILS
|
||||||
MIXERCONTROLDETAILS_LISTTEXTA* = record
|
MIXERCONTROLDETAILS_LISTTEXTA* {.final.} = object
|
||||||
dwParam1*: DWORD
|
dwParam1*: DWORD
|
||||||
dwParam2*: DWORD
|
dwParam2*: DWORD
|
||||||
szName*: array[0..Pred(MIXER_LONG_NAME_CHARS), CHAR]
|
szName*: array[0..Pred(MIXER_LONG_NAME_CHARS), CHAR]
|
||||||
|
|
@ -1489,7 +1489,7 @@ type
|
||||||
PMIXERCONTROLDETAILS_LISTTEXTA* = ptr MIXERCONTROLDETAILS_LISTTEXTA
|
PMIXERCONTROLDETAILS_LISTTEXTA* = ptr MIXERCONTROLDETAILS_LISTTEXTA
|
||||||
LPMIXERCONTROLDETAILS_LISTTEXTA* = ptr MIXERCONTROLDETAILS_LISTTEXTA
|
LPMIXERCONTROLDETAILS_LISTTEXTA* = ptr MIXERCONTROLDETAILS_LISTTEXTA
|
||||||
TMIXERCONTROLDETAILS_LISTTEXTA* = MIXERCONTROLDETAILS_LISTTEXTA
|
TMIXERCONTROLDETAILS_LISTTEXTA* = MIXERCONTROLDETAILS_LISTTEXTA
|
||||||
MIXERCONTROLDETAILS_LISTTEXTW* = record
|
MIXERCONTROLDETAILS_LISTTEXTW* {.final.} = object
|
||||||
dwParam1*: DWORD
|
dwParam1*: DWORD
|
||||||
dwParam2*: DWORD
|
dwParam2*: DWORD
|
||||||
szName*: array[0..Pred(MIXER_LONG_NAME_CHARS), WCHAR]
|
szName*: array[0..Pred(MIXER_LONG_NAME_CHARS), WCHAR]
|
||||||
|
|
@ -1510,19 +1510,19 @@ else:
|
||||||
LPMIXERCONTROLDETAILS_LISTTEXT* = LPMIXERCONTROLDETAILS_LISTTEXTA
|
LPMIXERCONTROLDETAILS_LISTTEXT* = LPMIXERCONTROLDETAILS_LISTTEXTA
|
||||||
type
|
type
|
||||||
TMIXERCONTROLDETAILS_LISTTEXT* = MIXERCONTROLDETAILS_LISTTEXT
|
TMIXERCONTROLDETAILS_LISTTEXT* = MIXERCONTROLDETAILS_LISTTEXT
|
||||||
MIXERCONTROLDETAILS_BOOLEAN* = record
|
MIXERCONTROLDETAILS_BOOLEAN* {.final.} = object
|
||||||
fValue*: int32
|
fValue*: int32
|
||||||
|
|
||||||
PMIXERCONTROLDETAILS_BOOLEAN* = ptr MIXERCONTROLDETAILS_BOOLEAN
|
PMIXERCONTROLDETAILS_BOOLEAN* = ptr MIXERCONTROLDETAILS_BOOLEAN
|
||||||
LPMIXERCONTROLDETAILS_BOOLEAN* = ptr MIXERCONTROLDETAILS_BOOLEAN
|
LPMIXERCONTROLDETAILS_BOOLEAN* = ptr MIXERCONTROLDETAILS_BOOLEAN
|
||||||
TMIXERCONTROLDETAILS_BOOLEAN* = MIXERCONTROLDETAILS_BOOLEAN
|
TMIXERCONTROLDETAILS_BOOLEAN* = MIXERCONTROLDETAILS_BOOLEAN
|
||||||
MIXERCONTROLDETAILS_SIGNED* = record
|
MIXERCONTROLDETAILS_SIGNED* {.final.} = object
|
||||||
lValue*: int32
|
lValue*: int32
|
||||||
|
|
||||||
PMIXERCONTROLDETAILS_SIGNED* = ptr MIXERCONTROLDETAILS_SIGNED
|
PMIXERCONTROLDETAILS_SIGNED* = ptr MIXERCONTROLDETAILS_SIGNED
|
||||||
LPMIXERCONTROLDETAILS_SIGNED* = ptr MIXERCONTROLDETAILS_SIGNED
|
LPMIXERCONTROLDETAILS_SIGNED* = ptr MIXERCONTROLDETAILS_SIGNED
|
||||||
TMIXERCONTROLDETAILS_SIGNED* = MIXERCONTROLDETAILS_SIGNED
|
TMIXERCONTROLDETAILS_SIGNED* = MIXERCONTROLDETAILS_SIGNED
|
||||||
MIXERCONTROLDETAILS_UNSIGNED* = record
|
MIXERCONTROLDETAILS_UNSIGNED* {.final.} = object
|
||||||
dwValue*: DWORD
|
dwValue*: DWORD
|
||||||
|
|
||||||
PMIXERCONTROLDETAILS_UNSIGNED* = ptr MIXERCONTROLDETAILS_UNSIGNED
|
PMIXERCONTROLDETAILS_UNSIGNED* = ptr MIXERCONTROLDETAILS_UNSIGNED
|
||||||
|
|
@ -1531,7 +1531,7 @@ type
|
||||||
LPTIMECALLBACK* = proc (uTimerID, uMsg: UINT, dwUser, dw1, dw2: DWORD){.
|
LPTIMECALLBACK* = proc (uTimerID, uMsg: UINT, dwUser, dw1, dw2: DWORD){.
|
||||||
stdcall.}
|
stdcall.}
|
||||||
TTIMECALLBACK* = LPTIMECALLBACK
|
TTIMECALLBACK* = LPTIMECALLBACK
|
||||||
timecaps* = record
|
timecaps* {.final.} = object
|
||||||
wPeriodMin*: UINT
|
wPeriodMin*: UINT
|
||||||
wPeriodMax*: UINT
|
wPeriodMax*: UINT
|
||||||
|
|
||||||
|
|
@ -1539,7 +1539,7 @@ type
|
||||||
NPTIMECAPS* = ptr timecaps
|
NPTIMECAPS* = ptr timecaps
|
||||||
LPTIMECAPS* = ptr timecaps
|
LPTIMECAPS* = ptr timecaps
|
||||||
TTIMECAS* = TIMECAPS
|
TTIMECAS* = TIMECAPS
|
||||||
JOYCAPSA* = record
|
JOYCAPSA* {.final.} = object
|
||||||
wMid*: int16
|
wMid*: int16
|
||||||
wPid*: int16
|
wPid*: int16
|
||||||
szPname*: array[0..Pred(MAXPNAMELEN), CHAR]
|
szPname*: array[0..Pred(MAXPNAMELEN), CHAR]
|
||||||
|
|
@ -1569,7 +1569,7 @@ type
|
||||||
NPJOYCAPSA* = ptr JOYCAPSA
|
NPJOYCAPSA* = ptr JOYCAPSA
|
||||||
LPJOYCAPSA* = ptr JOYCAPSA
|
LPJOYCAPSA* = ptr JOYCAPSA
|
||||||
TJOYCAPSA* = JOYCAPSA
|
TJOYCAPSA* = JOYCAPSA
|
||||||
JOYCAPSW* = record
|
JOYCAPSW* {.final.} = object
|
||||||
wMid*: int16
|
wMid*: int16
|
||||||
wPid*: int16
|
wPid*: int16
|
||||||
szPname*: array[0..Pred(MAXPNAMELEN), WCHAR]
|
szPname*: array[0..Pred(MAXPNAMELEN), WCHAR]
|
||||||
|
|
@ -1614,7 +1614,7 @@ else:
|
||||||
LPJOYCAPS* = LPJOYCAPSA
|
LPJOYCAPS* = LPJOYCAPSA
|
||||||
type
|
type
|
||||||
TJOYCAPS* = JOYCAPS
|
TJOYCAPS* = JOYCAPS
|
||||||
joyinfo* = record
|
joyinfo* {.final.} = object
|
||||||
wXpos*: UINT
|
wXpos*: UINT
|
||||||
wYpos*: UINT
|
wYpos*: UINT
|
||||||
wZpos*: UINT
|
wZpos*: UINT
|
||||||
|
|
@ -1624,7 +1624,7 @@ type
|
||||||
NPJOYINFO* = ptr joyinfo
|
NPJOYINFO* = ptr joyinfo
|
||||||
LPJOYINFO* = ptr joyinfo
|
LPJOYINFO* = ptr joyinfo
|
||||||
TJOYINFO* = JOYINFO
|
TJOYINFO* = JOYINFO
|
||||||
joyinfoex* = record
|
joyinfoex* {.final.} = object
|
||||||
dwSize*: DWORD
|
dwSize*: DWORD
|
||||||
dwFlags*: DWORD
|
dwFlags*: DWORD
|
||||||
wXpos*: UINT
|
wXpos*: UINT
|
||||||
|
|
@ -1648,7 +1648,7 @@ type
|
||||||
HMMIO* = THandle
|
HMMIO* = THandle
|
||||||
LPMMIOPROC* = proc (x1: LPSTR, x2: UINT, x3, x4: LPARAM): LRESULT{.stdcall.}
|
LPMMIOPROC* = proc (x1: LPSTR, x2: UINT, x3, x4: LPARAM): LRESULT{.stdcall.}
|
||||||
TMMIOPROC* = LPMMIOPROC
|
TMMIOPROC* = LPMMIOPROC
|
||||||
MMIOINFO* = record
|
MMIOINFO* {.final.} = object
|
||||||
dwFlags*: DWORD
|
dwFlags*: DWORD
|
||||||
fccIOProc*: FOURCC
|
fccIOProc*: FOURCC
|
||||||
pIOProc*: LPMMIOPROC
|
pIOProc*: LPMMIOPROC
|
||||||
|
|
@ -1671,7 +1671,7 @@ type
|
||||||
LPMMIOINFO* = ptr MMIOINFO
|
LPMMIOINFO* = ptr MMIOINFO
|
||||||
LPCMMIOINFO* = ptr MMIOINFO
|
LPCMMIOINFO* = ptr MMIOINFO
|
||||||
TMMIOINFO* = MMIOINFO
|
TMMIOINFO* = MMIOINFO
|
||||||
MMCKINFO* = record
|
MMCKINFO* {.final.} = object
|
||||||
ckid*: FOURCC
|
ckid*: FOURCC
|
||||||
cksize*: DWORD
|
cksize*: DWORD
|
||||||
fccType*: FOURCC
|
fccType*: FOURCC
|
||||||
|
|
@ -1687,13 +1687,13 @@ type
|
||||||
MCIDEVICEID* = UINT
|
MCIDEVICEID* = UINT
|
||||||
YIELDPROC* = proc (mciId: MCIDEVICEID, dwYieldData: DWORD): UINT{.stdcall.}
|
YIELDPROC* = proc (mciId: MCIDEVICEID, dwYieldData: DWORD): UINT{.stdcall.}
|
||||||
TYIELDPROC* = YIELDPROC
|
TYIELDPROC* = YIELDPROC
|
||||||
MCI_GENERIC_PARMS* = record
|
MCI_GENERIC_PARMS* {.final.} = object
|
||||||
dwCallback*: DWORD
|
dwCallback*: DWORD
|
||||||
|
|
||||||
PMCI_GENERIC_PARMS* = ptr MCI_GENERIC_PARMS
|
PMCI_GENERIC_PARMS* = ptr MCI_GENERIC_PARMS
|
||||||
LPMCI_GENERIC_PARMS* = ptr MCI_GENERIC_PARMS
|
LPMCI_GENERIC_PARMS* = ptr MCI_GENERIC_PARMS
|
||||||
TMCI_GENERIC_PARMS* = MCI_GENERIC_PARMS
|
TMCI_GENERIC_PARMS* = MCI_GENERIC_PARMS
|
||||||
MCI_OPEN_PARMSA* = record
|
MCI_OPEN_PARMSA* {.final.} = object
|
||||||
dwCallback*: DWORD
|
dwCallback*: DWORD
|
||||||
wDeviceID*: MCIDEVICEID
|
wDeviceID*: MCIDEVICEID
|
||||||
lpstrDeviceType*: LPCSTR
|
lpstrDeviceType*: LPCSTR
|
||||||
|
|
@ -1703,7 +1703,7 @@ type
|
||||||
PMCI_OPEN_PARMSA* = ptr MCI_OPEN_PARMSA
|
PMCI_OPEN_PARMSA* = ptr MCI_OPEN_PARMSA
|
||||||
LPMCI_OPEN_PARMSA* = ptr MCI_OPEN_PARMSA
|
LPMCI_OPEN_PARMSA* = ptr MCI_OPEN_PARMSA
|
||||||
TMCI_OPEN_PARMSA* = MCI_OPEN_PARMSA
|
TMCI_OPEN_PARMSA* = MCI_OPEN_PARMSA
|
||||||
MCI_OPEN_PARMSW* = record
|
MCI_OPEN_PARMSW* {.final.} = object
|
||||||
dwCallback*: DWORD
|
dwCallback*: DWORD
|
||||||
wDeviceID*: MCIDEVICEID
|
wDeviceID*: MCIDEVICEID
|
||||||
lpstrDeviceType*: LPCWSTR
|
lpstrDeviceType*: LPCWSTR
|
||||||
|
|
@ -1726,7 +1726,7 @@ else:
|
||||||
LPMCI_OPEN_PARMS* = LPMCI_OPEN_PARMSA
|
LPMCI_OPEN_PARMS* = LPMCI_OPEN_PARMSA
|
||||||
type
|
type
|
||||||
TMCI_OPEN_PARMS* = MCI_OPEN_PARMS
|
TMCI_OPEN_PARMS* = MCI_OPEN_PARMS
|
||||||
MCI_PLAY_PARMS* = record
|
MCI_PLAY_PARMS* {.final.} = object
|
||||||
dwCallback*: DWORD
|
dwCallback*: DWORD
|
||||||
dwFrom*: DWORD
|
dwFrom*: DWORD
|
||||||
dwTo*: DWORD
|
dwTo*: DWORD
|
||||||
|
|
@ -1734,14 +1734,14 @@ type
|
||||||
PMCI_PLAY_PARMS* = ptr MCI_PLAY_PARMS
|
PMCI_PLAY_PARMS* = ptr MCI_PLAY_PARMS
|
||||||
LPMCI_PLAY_PARMS* = ptr MCI_PLAY_PARMS
|
LPMCI_PLAY_PARMS* = ptr MCI_PLAY_PARMS
|
||||||
TMCI_PLAY_PARMS* = MCI_PLAY_PARMS
|
TMCI_PLAY_PARMS* = MCI_PLAY_PARMS
|
||||||
MCI_SEEK_PARMS* = record
|
MCI_SEEK_PARMS* {.final.} = object
|
||||||
dwCallback*: DWORD
|
dwCallback*: DWORD
|
||||||
dwTo*: DWORD
|
dwTo*: DWORD
|
||||||
|
|
||||||
PMCI_SEEK_PARMS* = ptr MCI_SEEK_PARMS
|
PMCI_SEEK_PARMS* = ptr MCI_SEEK_PARMS
|
||||||
LPMCI_SEEK_PARMS* = ptr MCI_SEEK_PARMS
|
LPMCI_SEEK_PARMS* = ptr MCI_SEEK_PARMS
|
||||||
TMCI_SEEK_PARMS* = MCI_SEEK_PARMS
|
TMCI_SEEK_PARMS* = MCI_SEEK_PARMS
|
||||||
MCI_STATUS_PARMS* = record
|
MCI_STATUS_PARMS* {.final.} = object
|
||||||
dwCallback*: DWORD
|
dwCallback*: DWORD
|
||||||
dwReturn*: DWORD
|
dwReturn*: DWORD
|
||||||
dwItem*: DWORD
|
dwItem*: DWORD
|
||||||
|
|
@ -1750,14 +1750,14 @@ type
|
||||||
PMCI_STATUS_PARMS* = ptr MCI_STATUS_PARMS
|
PMCI_STATUS_PARMS* = ptr MCI_STATUS_PARMS
|
||||||
LPMCI_STATUS_PARMS* = ptr MCI_STATUS_PARMS
|
LPMCI_STATUS_PARMS* = ptr MCI_STATUS_PARMS
|
||||||
TMCI_STATUS_PARMS* = MCI_STATUS_PARMS
|
TMCI_STATUS_PARMS* = MCI_STATUS_PARMS
|
||||||
MCI_INFO_PARMSA* = record
|
MCI_INFO_PARMSA* {.final.} = object
|
||||||
dwCallback*: DWORD
|
dwCallback*: DWORD
|
||||||
lpstrReturn*: cstring
|
lpstrReturn*: cstring
|
||||||
dwRetSize*: DWORD
|
dwRetSize*: DWORD
|
||||||
|
|
||||||
LPMCI_INFO_PARMSA* = ptr MCI_INFO_PARMSA
|
LPMCI_INFO_PARMSA* = ptr MCI_INFO_PARMSA
|
||||||
TMCI_INFO_PARMSA* = MCI_INFO_PARMSA
|
TMCI_INFO_PARMSA* = MCI_INFO_PARMSA
|
||||||
MCI_INFO_PARMSW* = record
|
MCI_INFO_PARMSW* {.final.} = object
|
||||||
dwCallback*: DWORD
|
dwCallback*: DWORD
|
||||||
lpstrReturn*: LPWSTR
|
lpstrReturn*: LPWSTR
|
||||||
dwRetSize*: DWORD
|
dwRetSize*: DWORD
|
||||||
|
|
@ -1775,7 +1775,7 @@ else:
|
||||||
LPMCI_INFO_PARMS* = LPMCI_INFO_PARMSA
|
LPMCI_INFO_PARMS* = LPMCI_INFO_PARMSA
|
||||||
type
|
type
|
||||||
TMCI_INFO_PARMS* = MCI_INFO_PARMS
|
TMCI_INFO_PARMS* = MCI_INFO_PARMS
|
||||||
MCI_GETDEVCAPS_PARMS* = record
|
MCI_GETDEVCAPS_PARMS* {.final.} = object
|
||||||
dwCallback*: DWORD
|
dwCallback*: DWORD
|
||||||
dwReturn*: DWORD
|
dwReturn*: DWORD
|
||||||
dwItem*: DWORD
|
dwItem*: DWORD
|
||||||
|
|
@ -1783,7 +1783,7 @@ type
|
||||||
PMCI_GETDEVCAPS_PARMS* = ptr MCI_GETDEVCAPS_PARMS
|
PMCI_GETDEVCAPS_PARMS* = ptr MCI_GETDEVCAPS_PARMS
|
||||||
LPMCI_GETDEVCAPS_PARMS* = ptr MCI_GETDEVCAPS_PARMS
|
LPMCI_GETDEVCAPS_PARMS* = ptr MCI_GETDEVCAPS_PARMS
|
||||||
TMCI_GETDEVCAPS_PARMS* = MCI_GETDEVCAPS_PARMS
|
TMCI_GETDEVCAPS_PARMS* = MCI_GETDEVCAPS_PARMS
|
||||||
MCI_SYSINFO_PARMSA* = record
|
MCI_SYSINFO_PARMSA* {.final.} = object
|
||||||
dwCallback*: DWORD
|
dwCallback*: DWORD
|
||||||
lpstrReturn*: cstring
|
lpstrReturn*: cstring
|
||||||
dwRetSize*: DWORD
|
dwRetSize*: DWORD
|
||||||
|
|
@ -1793,7 +1793,7 @@ type
|
||||||
PMCI_SYSINFO_PARMSA* = ptr MCI_SYSINFO_PARMSA
|
PMCI_SYSINFO_PARMSA* = ptr MCI_SYSINFO_PARMSA
|
||||||
LPMCI_SYSINFO_PARMSA* = ptr MCI_SYSINFO_PARMSA
|
LPMCI_SYSINFO_PARMSA* = ptr MCI_SYSINFO_PARMSA
|
||||||
TMCI_SYSINFO_PARMSA* = MCI_SYSINFO_PARMSA
|
TMCI_SYSINFO_PARMSA* = MCI_SYSINFO_PARMSA
|
||||||
MCI_SYSINFO_PARMSW* = record
|
MCI_SYSINFO_PARMSW* {.final.} = object
|
||||||
dwCallback*: DWORD
|
dwCallback*: DWORD
|
||||||
lpstrReturn*: LPWSTR
|
lpstrReturn*: LPWSTR
|
||||||
dwRetSize*: DWORD
|
dwRetSize*: DWORD
|
||||||
|
|
@ -1816,7 +1816,7 @@ else:
|
||||||
LPMCI_SYSINFO_PARMS* = LPMCI_SYSINFO_PARMSA
|
LPMCI_SYSINFO_PARMS* = LPMCI_SYSINFO_PARMSA
|
||||||
type
|
type
|
||||||
TMCI_SYSINFO_PARMS* = MCI_SYSINFO_PARMS
|
TMCI_SYSINFO_PARMS* = MCI_SYSINFO_PARMS
|
||||||
MCI_SET_PARMS* = record
|
MCI_SET_PARMS* {.final.} = object
|
||||||
dwCallback*: DWORD
|
dwCallback*: DWORD
|
||||||
dwTimeFormat*: DWORD
|
dwTimeFormat*: DWORD
|
||||||
dwAudio*: DWORD
|
dwAudio*: DWORD
|
||||||
|
|
@ -1824,7 +1824,7 @@ type
|
||||||
PMCI_SET_PARMS* = ptr MCI_SET_PARMS
|
PMCI_SET_PARMS* = ptr MCI_SET_PARMS
|
||||||
LPMCI_SET_PARMS* = ptr MCI_SET_PARMS
|
LPMCI_SET_PARMS* = ptr MCI_SET_PARMS
|
||||||
TMCI_SET_PARMS* = MCI_SET_PARMS
|
TMCI_SET_PARMS* = MCI_SET_PARMS
|
||||||
MCI_BREAK_PARMS* = record
|
MCI_BREAK_PARMS* {.final.} = object
|
||||||
dwCallback*: DWORD
|
dwCallback*: DWORD
|
||||||
nVirtKey*: int32
|
nVirtKey*: int32
|
||||||
hwndBreak*: HWND
|
hwndBreak*: HWND
|
||||||
|
|
@ -1832,14 +1832,14 @@ type
|
||||||
PMCI_BREAK_PARMS* = ptr MCI_BREAK_PARMS
|
PMCI_BREAK_PARMS* = ptr MCI_BREAK_PARMS
|
||||||
LPMCI_BREAK_PARMS* = ptr MCI_BREAK_PARMS
|
LPMCI_BREAK_PARMS* = ptr MCI_BREAK_PARMS
|
||||||
TMCI_BREAK_PARMS* = MCI_BREAK_PARMS
|
TMCI_BREAK_PARMS* = MCI_BREAK_PARMS
|
||||||
MCI_SAVE_PARMSA* = record
|
MCI_SAVE_PARMSA* {.final.} = object
|
||||||
dwCallback*: DWORD
|
dwCallback*: DWORD
|
||||||
lpfilename*: LPCSTR
|
lpfilename*: LPCSTR
|
||||||
|
|
||||||
PMCI_SAVE_PARMSA* = ptr MCI_SAVE_PARMSA
|
PMCI_SAVE_PARMSA* = ptr MCI_SAVE_PARMSA
|
||||||
LPMCI_SAVE_PARMSA* = ptr MCI_SAVE_PARMSA
|
LPMCI_SAVE_PARMSA* = ptr MCI_SAVE_PARMSA
|
||||||
TMCI_SAVE_PARMSA* = MCI_SAVE_PARMSA
|
TMCI_SAVE_PARMSA* = MCI_SAVE_PARMSA
|
||||||
MCI_SAVE_PARMSW* = record
|
MCI_SAVE_PARMSW* {.final.} = object
|
||||||
dwCallback*: DWORD
|
dwCallback*: DWORD
|
||||||
lpfilename*: LPCWSTR
|
lpfilename*: LPCWSTR
|
||||||
|
|
||||||
|
|
@ -1859,14 +1859,14 @@ else:
|
||||||
LPMCI_SAVE_PARMS* = LPMCI_SAVE_PARMSA
|
LPMCI_SAVE_PARMS* = LPMCI_SAVE_PARMSA
|
||||||
type
|
type
|
||||||
TMCI_SAVE_PARMS* = MCI_SAVE_PARMS
|
TMCI_SAVE_PARMS* = MCI_SAVE_PARMS
|
||||||
MCI_LOAD_PARMSA* = record
|
MCI_LOAD_PARMSA* {.final.} = object
|
||||||
dwCallback*: DWORD
|
dwCallback*: DWORD
|
||||||
lpfilename*: LPCSTR
|
lpfilename*: LPCSTR
|
||||||
|
|
||||||
PMCI_LOAD_PARMSA* = ptr MCI_LOAD_PARMSA
|
PMCI_LOAD_PARMSA* = ptr MCI_LOAD_PARMSA
|
||||||
LPMCI_LOAD_PARMSA* = ptr MCI_LOAD_PARMSA
|
LPMCI_LOAD_PARMSA* = ptr MCI_LOAD_PARMSA
|
||||||
TMCI_LOAD_PARMSA* = MCI_LOAD_PARMSA
|
TMCI_LOAD_PARMSA* = MCI_LOAD_PARMSA
|
||||||
MCI_LOAD_PARMSW* = record
|
MCI_LOAD_PARMSW* {.final.} = object
|
||||||
dwCallback*: DWORD
|
dwCallback*: DWORD
|
||||||
lpfilename*: LPCWSTR
|
lpfilename*: LPCWSTR
|
||||||
|
|
||||||
|
|
@ -1886,14 +1886,14 @@ else:
|
||||||
LPMCI_LOAD_PARMS* = LPMCI_LOAD_PARMSA
|
LPMCI_LOAD_PARMS* = LPMCI_LOAD_PARMSA
|
||||||
type
|
type
|
||||||
TMCI_LOAD_PARMS* = MCI_LOAD_PARMS
|
TMCI_LOAD_PARMS* = MCI_LOAD_PARMS
|
||||||
MCI_RECORD_PARMS* = record
|
MCI_RECORD_PARMS* {.final.} = object
|
||||||
dwCallback*: DWORD
|
dwCallback*: DWORD
|
||||||
dwFrom*: DWORD
|
dwFrom*: DWORD
|
||||||
dwTo*: DWORD
|
dwTo*: DWORD
|
||||||
|
|
||||||
LPMCI_RECORD_PARMS* = ptr MCI_RECORD_PARMS
|
LPMCI_RECORD_PARMS* = ptr MCI_RECORD_PARMS
|
||||||
TMCI_RECORD_PARMS* = MCI_RECORD_PARMS
|
TMCI_RECORD_PARMS* = MCI_RECORD_PARMS
|
||||||
MCI_VD_PLAY_PARMS* = record
|
MCI_VD_PLAY_PARMS* {.final.} = object
|
||||||
dwCallback*: DWORD
|
dwCallback*: DWORD
|
||||||
dwFrom*: DWORD
|
dwFrom*: DWORD
|
||||||
dwTo*: DWORD
|
dwTo*: DWORD
|
||||||
|
|
@ -1902,20 +1902,20 @@ type
|
||||||
PMCI_VD_PLAY_PARMS* = ptr MCI_VD_PLAY_PARMS
|
PMCI_VD_PLAY_PARMS* = ptr MCI_VD_PLAY_PARMS
|
||||||
LPMCI_VD_PLAY_PARMS* = ptr MCI_VD_PLAY_PARMS
|
LPMCI_VD_PLAY_PARMS* = ptr MCI_VD_PLAY_PARMS
|
||||||
TMCI_VD_PLAY_PARMS* = MCI_VD_PLAY_PARMS
|
TMCI_VD_PLAY_PARMS* = MCI_VD_PLAY_PARMS
|
||||||
MCI_VD_STEP_PARMS* = record
|
MCI_VD_STEP_PARMS* {.final.} = object
|
||||||
dwCallback*: DWORD
|
dwCallback*: DWORD
|
||||||
dwFrames*: DWORD
|
dwFrames*: DWORD
|
||||||
|
|
||||||
PMCI_VD_STEP_PARMS* = ptr MCI_VD_STEP_PARMS
|
PMCI_VD_STEP_PARMS* = ptr MCI_VD_STEP_PARMS
|
||||||
LPMCI_VD_STEP_PARMS* = ptr MCI_VD_STEP_PARMS
|
LPMCI_VD_STEP_PARMS* = ptr MCI_VD_STEP_PARMS
|
||||||
MCI_VD_ESCAPE_PARMSA* = record
|
MCI_VD_ESCAPE_PARMSA* {.final.} = object
|
||||||
dwCallback*: DWORD
|
dwCallback*: DWORD
|
||||||
lpstrCommand*: LPCSTR
|
lpstrCommand*: LPCSTR
|
||||||
|
|
||||||
PMCI_VD_ESCAPE_PARMSA* = ptr MCI_VD_ESCAPE_PARMSA
|
PMCI_VD_ESCAPE_PARMSA* = ptr MCI_VD_ESCAPE_PARMSA
|
||||||
LPMCI_VD_ESCAPE_PARMSA* = ptr MCI_VD_ESCAPE_PARMSA
|
LPMCI_VD_ESCAPE_PARMSA* = ptr MCI_VD_ESCAPE_PARMSA
|
||||||
TMCI_VD_ESCAPE_PARMSA* = MCI_VD_ESCAPE_PARMSA
|
TMCI_VD_ESCAPE_PARMSA* = MCI_VD_ESCAPE_PARMSA
|
||||||
MCI_VD_ESCAPE_PARMSW* = record
|
MCI_VD_ESCAPE_PARMSW* {.final.} = object
|
||||||
dwCallback*: DWORD
|
dwCallback*: DWORD
|
||||||
lpstrCommand*: LPCWSTR
|
lpstrCommand*: LPCWSTR
|
||||||
|
|
||||||
|
|
@ -1935,7 +1935,7 @@ else:
|
||||||
LPMCI_VD_ESCAPE_PARMS* = LPMCI_VD_ESCAPE_PARMSA
|
LPMCI_VD_ESCAPE_PARMS* = LPMCI_VD_ESCAPE_PARMSA
|
||||||
type
|
type
|
||||||
TMCI_VD_ESCAPE_PARMS* = MCI_VD_ESCAPE_PARMS
|
TMCI_VD_ESCAPE_PARMS* = MCI_VD_ESCAPE_PARMS
|
||||||
MCI_WAVE_OPEN_PARMSA* = record
|
MCI_WAVE_OPEN_PARMSA* {.final.} = object
|
||||||
dwCallback*: DWORD
|
dwCallback*: DWORD
|
||||||
wDeviceID*: MCIDEVICEID
|
wDeviceID*: MCIDEVICEID
|
||||||
lpstrDeviceType*: LPCSTR
|
lpstrDeviceType*: LPCSTR
|
||||||
|
|
@ -1946,7 +1946,7 @@ type
|
||||||
PMCI_WAVE_OPEN_PARMSA* = ptr MCI_WAVE_OPEN_PARMSA
|
PMCI_WAVE_OPEN_PARMSA* = ptr MCI_WAVE_OPEN_PARMSA
|
||||||
LPMCI_WAVE_OPEN_PARMSA* = ptr MCI_WAVE_OPEN_PARMSA
|
LPMCI_WAVE_OPEN_PARMSA* = ptr MCI_WAVE_OPEN_PARMSA
|
||||||
TMCI_WAVE_OPEN_PARMSA* = MCI_WAVE_OPEN_PARMSA
|
TMCI_WAVE_OPEN_PARMSA* = MCI_WAVE_OPEN_PARMSA
|
||||||
MCI_WAVE_OPEN_PARMSW* = record
|
MCI_WAVE_OPEN_PARMSW* {.final.} = object
|
||||||
dwCallback*: DWORD
|
dwCallback*: DWORD
|
||||||
wDeviceID*: MCIDEVICEID
|
wDeviceID*: MCIDEVICEID
|
||||||
lpstrDeviceType*: LPCWSTR
|
lpstrDeviceType*: LPCWSTR
|
||||||
|
|
@ -1970,7 +1970,7 @@ else:
|
||||||
LPMCI_WAVE_OPEN_PARMS* = LPMCI_WAVE_OPEN_PARMSA
|
LPMCI_WAVE_OPEN_PARMS* = LPMCI_WAVE_OPEN_PARMSA
|
||||||
type
|
type
|
||||||
TMCI_WAVE_OPEN_PARMS* = MCI_WAVE_OPEN_PARMS
|
TMCI_WAVE_OPEN_PARMS* = MCI_WAVE_OPEN_PARMS
|
||||||
MCI_WAVE_DELETE_PARMS* = record
|
MCI_WAVE_DELETE_PARMS* {.final.} = object
|
||||||
dwCallback*: DWORD
|
dwCallback*: DWORD
|
||||||
dwFrom*: DWORD
|
dwFrom*: DWORD
|
||||||
dwTo*: DWORD
|
dwTo*: DWORD
|
||||||
|
|
@ -1978,7 +1978,7 @@ type
|
||||||
PMCI_WAVE_DELETE_PARMS* = ptr MCI_WAVE_DELETE_PARMS
|
PMCI_WAVE_DELETE_PARMS* = ptr MCI_WAVE_DELETE_PARMS
|
||||||
LPMCI_WAVE_DELETE_PARMS* = ptr MCI_WAVE_DELETE_PARMS
|
LPMCI_WAVE_DELETE_PARMS* = ptr MCI_WAVE_DELETE_PARMS
|
||||||
TMCI_WAVE_DELETE_PARMS* = MCI_WAVE_DELETE_PARMS
|
TMCI_WAVE_DELETE_PARMS* = MCI_WAVE_DELETE_PARMS
|
||||||
MCI_WAVE_SET_PARMS* = record
|
MCI_WAVE_SET_PARMS* {.final.} = object
|
||||||
dwCallback*: DWORD
|
dwCallback*: DWORD
|
||||||
dwTimeFormat*: DWORD
|
dwTimeFormat*: DWORD
|
||||||
dwAudio*: DWORD
|
dwAudio*: DWORD
|
||||||
|
|
@ -1998,7 +1998,7 @@ type
|
||||||
PMCI_WAVE_SET_PARMS* = ptr MCI_WAVE_SET_PARMS
|
PMCI_WAVE_SET_PARMS* = ptr MCI_WAVE_SET_PARMS
|
||||||
LPMCI_WAVE_SET_PARMS* = ptr MCI_WAVE_SET_PARMS
|
LPMCI_WAVE_SET_PARMS* = ptr MCI_WAVE_SET_PARMS
|
||||||
TMCI_WAVE_SET_PARMS* = MCI_WAVE_SET_PARMS
|
TMCI_WAVE_SET_PARMS* = MCI_WAVE_SET_PARMS
|
||||||
MCI_SEQ_SET_PARMS* = record
|
MCI_SEQ_SET_PARMS* {.final.} = object
|
||||||
dwCallback*: DWORD
|
dwCallback*: DWORD
|
||||||
dwTimeFormat*: DWORD
|
dwTimeFormat*: DWORD
|
||||||
dwAudio*: DWORD
|
dwAudio*: DWORD
|
||||||
|
|
@ -2011,7 +2011,7 @@ type
|
||||||
PMCI_SEQ_SET_PARMS* = ptr MCI_SEQ_SET_PARMS
|
PMCI_SEQ_SET_PARMS* = ptr MCI_SEQ_SET_PARMS
|
||||||
LPMCI_SEQ_SET_PARMS* = ptr MCI_SEQ_SET_PARMS
|
LPMCI_SEQ_SET_PARMS* = ptr MCI_SEQ_SET_PARMS
|
||||||
TMCI_SEQ_SET_PARMS* = MCI_SEQ_SET_PARMS
|
TMCI_SEQ_SET_PARMS* = MCI_SEQ_SET_PARMS
|
||||||
MCI_ANIM_OPEN_PARMSA* = record
|
MCI_ANIM_OPEN_PARMSA* {.final.} = object
|
||||||
dwCallback*: DWORD
|
dwCallback*: DWORD
|
||||||
wDeviceID*: MCIDEVICEID
|
wDeviceID*: MCIDEVICEID
|
||||||
lpstrDeviceType*: LPCSTR
|
lpstrDeviceType*: LPCSTR
|
||||||
|
|
@ -2023,7 +2023,7 @@ type
|
||||||
PMCI_ANIM_OPEN_PARMSA* = ptr MCI_ANIM_OPEN_PARMSA
|
PMCI_ANIM_OPEN_PARMSA* = ptr MCI_ANIM_OPEN_PARMSA
|
||||||
LPMCI_ANIM_OPEN_PARMSA* = ptr MCI_ANIM_OPEN_PARMSA
|
LPMCI_ANIM_OPEN_PARMSA* = ptr MCI_ANIM_OPEN_PARMSA
|
||||||
TMCI_ANIM_OPEN_PARMSA* = MCI_ANIM_OPEN_PARMSA
|
TMCI_ANIM_OPEN_PARMSA* = MCI_ANIM_OPEN_PARMSA
|
||||||
MCI_ANIM_OPEN_PARMSW* = record
|
MCI_ANIM_OPEN_PARMSW* {.final.} = object
|
||||||
dwCallback*: DWORD
|
dwCallback*: DWORD
|
||||||
wDeviceID*: MCIDEVICEID
|
wDeviceID*: MCIDEVICEID
|
||||||
lpstrDeviceType*: LPCWSTR
|
lpstrDeviceType*: LPCWSTR
|
||||||
|
|
@ -2047,7 +2047,7 @@ else:
|
||||||
LPMCI_ANIM_OPEN_PARMS* = LPMCI_ANIM_OPEN_PARMSA
|
LPMCI_ANIM_OPEN_PARMS* = LPMCI_ANIM_OPEN_PARMSA
|
||||||
type
|
type
|
||||||
TMCI_ANIM_OPEN_PARMS* = MCI_ANIM_OPEN_PARMS
|
TMCI_ANIM_OPEN_PARMS* = MCI_ANIM_OPEN_PARMS
|
||||||
MCI_ANIM_WINDOW_PARMSW* = record
|
MCI_ANIM_WINDOW_PARMSW* {.final.} = object
|
||||||
dwCallback*: DWORD
|
dwCallback*: DWORD
|
||||||
hWnd*: HWND
|
hWnd*: HWND
|
||||||
nCmdShow*: UINT
|
nCmdShow*: UINT
|
||||||
|
|
@ -2056,14 +2056,14 @@ type
|
||||||
PMCI_ANIM_WINDOW_PARMSW* = ptr MCI_ANIM_WINDOW_PARMSW
|
PMCI_ANIM_WINDOW_PARMSW* = ptr MCI_ANIM_WINDOW_PARMSW
|
||||||
LPMCI_ANIM_WINDOW_PARMSW* = ptr MCI_ANIM_WINDOW_PARMSW
|
LPMCI_ANIM_WINDOW_PARMSW* = ptr MCI_ANIM_WINDOW_PARMSW
|
||||||
TMCI_ANIM_WINDOW_PARMSW* = MCI_ANIM_WINDOW_PARMSW
|
TMCI_ANIM_WINDOW_PARMSW* = MCI_ANIM_WINDOW_PARMSW
|
||||||
MCI_ANIM_STEP_PARMS* = record
|
MCI_ANIM_STEP_PARMS* {.final.} = object
|
||||||
dwCallback*: DWORD
|
dwCallback*: DWORD
|
||||||
dwFrames*: DWORD
|
dwFrames*: DWORD
|
||||||
|
|
||||||
PMCI_ANIM_STEP_PARMS* = ptr MCI_ANIM_STEP_PARMS
|
PMCI_ANIM_STEP_PARMS* = ptr MCI_ANIM_STEP_PARMS
|
||||||
LPMCI_ANIM_STEP_PARMS* = ptr MCI_ANIM_STEP_PARMS
|
LPMCI_ANIM_STEP_PARMS* = ptr MCI_ANIM_STEP_PARMS
|
||||||
TMCI_ANIM_STEP_PARMS* = MCI_ANIM_STEP_PARMS
|
TMCI_ANIM_STEP_PARMS* = MCI_ANIM_STEP_PARMS
|
||||||
MCI_ANIM_WINDOW_PARMSA* = record
|
MCI_ANIM_WINDOW_PARMSA* {.final.} = object
|
||||||
dwCallback*: DWORD
|
dwCallback*: DWORD
|
||||||
hWnd*: HWND
|
hWnd*: HWND
|
||||||
nCmdShow*: UINT
|
nCmdShow*: UINT
|
||||||
|
|
@ -2072,7 +2072,7 @@ type
|
||||||
PMCI_ANIM_WINDOW_PARMSA* = ptr MCI_ANIM_WINDOW_PARMSA
|
PMCI_ANIM_WINDOW_PARMSA* = ptr MCI_ANIM_WINDOW_PARMSA
|
||||||
LPMCI_ANIM_WINDOW_PARMSA* = ptr MCI_ANIM_WINDOW_PARMSA
|
LPMCI_ANIM_WINDOW_PARMSA* = ptr MCI_ANIM_WINDOW_PARMSA
|
||||||
TMCI_ANIM_WINDOW_PARMSA* = MCI_ANIM_WINDOW_PARMSA
|
TMCI_ANIM_WINDOW_PARMSA* = MCI_ANIM_WINDOW_PARMSA
|
||||||
MCI_ANIM_PLAY_PARMS* = record
|
MCI_ANIM_PLAY_PARMS* {.final.} = object
|
||||||
dwCallback*: DWORD
|
dwCallback*: DWORD
|
||||||
dwFrom*: DWORD
|
dwFrom*: DWORD
|
||||||
dwTo*: DWORD
|
dwTo*: DWORD
|
||||||
|
|
@ -2092,14 +2092,14 @@ else:
|
||||||
PMCI_ANIM_WINDOW_PARMS* = PMCI_ANIM_WINDOW_PARMSA
|
PMCI_ANIM_WINDOW_PARMS* = PMCI_ANIM_WINDOW_PARMSA
|
||||||
LPMCI_ANIM_WINDOW_PARMS* = LPMCI_ANIM_WINDOW_PARMSA
|
LPMCI_ANIM_WINDOW_PARMS* = LPMCI_ANIM_WINDOW_PARMSA
|
||||||
type
|
type
|
||||||
MCI_ANIM_RECT_PARMS* = record
|
MCI_ANIM_RECT_PARMS* {.final.} = object
|
||||||
dwCallback*: DWORD
|
dwCallback*: DWORD
|
||||||
rc*: TRECT
|
rc*: TRECT
|
||||||
|
|
||||||
PMCI_ANIM_RECT_PARMS* = ptr MCI_ANIM_RECT_PARMS
|
PMCI_ANIM_RECT_PARMS* = ptr MCI_ANIM_RECT_PARMS
|
||||||
LPMCI_ANIM_RECT_PARMS* = ptr MCI_ANIM_RECT_PARMS
|
LPMCI_ANIM_RECT_PARMS* = ptr MCI_ANIM_RECT_PARMS
|
||||||
TMCI_ANIM_RECT_PARMS* = MCI_ANIM_RECT_PARMS
|
TMCI_ANIM_RECT_PARMS* = MCI_ANIM_RECT_PARMS
|
||||||
MCI_ANIM_UPDATE_PARMS* = record
|
MCI_ANIM_UPDATE_PARMS* {.final.} = object
|
||||||
dwCallback*: DWORD
|
dwCallback*: DWORD
|
||||||
rc*: TRECT
|
rc*: TRECT
|
||||||
hDC*: HDC
|
hDC*: HDC
|
||||||
|
|
@ -2107,7 +2107,7 @@ type
|
||||||
PMCI_ANIM_UPDATE_PARMS* = ptr MCI_ANIM_UPDATE_PARMS
|
PMCI_ANIM_UPDATE_PARMS* = ptr MCI_ANIM_UPDATE_PARMS
|
||||||
LPMCI_ANIM_UPDATE_PARMS* = ptr MCI_ANIM_UPDATE_PARMS
|
LPMCI_ANIM_UPDATE_PARMS* = ptr MCI_ANIM_UPDATE_PARMS
|
||||||
TMCI_ANIM_UPDATE_PARMS* = MCI_ANIM_UPDATE_PARMS
|
TMCI_ANIM_UPDATE_PARMS* = MCI_ANIM_UPDATE_PARMS
|
||||||
MCI_OVLY_OPEN_PARMSA* = record
|
MCI_OVLY_OPEN_PARMSA* {.final.} = object
|
||||||
dwCallback*: DWORD
|
dwCallback*: DWORD
|
||||||
wDeviceID*: MCIDEVICEID
|
wDeviceID*: MCIDEVICEID
|
||||||
lpstrDeviceType*: LPCSTR
|
lpstrDeviceType*: LPCSTR
|
||||||
|
|
@ -2119,7 +2119,7 @@ type
|
||||||
PMCI_OVLY_OPEN_PARMSA* = ptr MCI_OVLY_OPEN_PARMSA
|
PMCI_OVLY_OPEN_PARMSA* = ptr MCI_OVLY_OPEN_PARMSA
|
||||||
LPMCI_OVLY_OPEN_PARMSA* = ptr MCI_OVLY_OPEN_PARMSA
|
LPMCI_OVLY_OPEN_PARMSA* = ptr MCI_OVLY_OPEN_PARMSA
|
||||||
TMCI_OVLY_OPEN_PARMSA* = MCI_OVLY_OPEN_PARMSA
|
TMCI_OVLY_OPEN_PARMSA* = MCI_OVLY_OPEN_PARMSA
|
||||||
MCI_OVLY_OPEN_PARMSW* = record
|
MCI_OVLY_OPEN_PARMSW* {.final.} = object
|
||||||
dwCallback*: DWORD
|
dwCallback*: DWORD
|
||||||
wDeviceID*: MCIDEVICEID
|
wDeviceID*: MCIDEVICEID
|
||||||
lpstrDeviceType*: LPCWSTR
|
lpstrDeviceType*: LPCWSTR
|
||||||
|
|
@ -2144,7 +2144,7 @@ else:
|
||||||
LPMCI_OVLY_OPEN_PARMS* = LPMCI_OVLY_OPEN_PARMSA
|
LPMCI_OVLY_OPEN_PARMS* = LPMCI_OVLY_OPEN_PARMSA
|
||||||
type
|
type
|
||||||
TMCI_OVLY_OPEN_PARMS* = MCI_OVLY_OPEN_PARMS
|
TMCI_OVLY_OPEN_PARMS* = MCI_OVLY_OPEN_PARMS
|
||||||
MCI_OVLY_WINDOW_PARMSA* = record
|
MCI_OVLY_WINDOW_PARMSA* {.final.} = object
|
||||||
dwCallback*: DWORD
|
dwCallback*: DWORD
|
||||||
hWnd*: HWND
|
hWnd*: HWND
|
||||||
nCmdShow*: UINT
|
nCmdShow*: UINT
|
||||||
|
|
@ -2153,7 +2153,7 @@ type
|
||||||
PMCI_OVLY_WINDOW_PARMSA* = ptr MCI_OVLY_WINDOW_PARMSA
|
PMCI_OVLY_WINDOW_PARMSA* = ptr MCI_OVLY_WINDOW_PARMSA
|
||||||
LPMCI_OVLY_WINDOW_PARMSA* = ptr MCI_OVLY_WINDOW_PARMSA
|
LPMCI_OVLY_WINDOW_PARMSA* = ptr MCI_OVLY_WINDOW_PARMSA
|
||||||
TMCI_OVLY_WINDOW_PARMSA* = MCI_OVLY_WINDOW_PARMSA
|
TMCI_OVLY_WINDOW_PARMSA* = MCI_OVLY_WINDOW_PARMSA
|
||||||
MCI_OVLY_WINDOW_PARMSW* = record
|
MCI_OVLY_WINDOW_PARMSW* {.final.} = object
|
||||||
dwCallback*: DWORD
|
dwCallback*: DWORD
|
||||||
hWnd*: HWND
|
hWnd*: HWND
|
||||||
nCmdShow*: UINT
|
nCmdShow*: UINT
|
||||||
|
|
@ -2175,14 +2175,14 @@ else:
|
||||||
LPMCI_OVLY_WINDOW_PARMS* = LPMCI_OVLY_WINDOW_PARMSA
|
LPMCI_OVLY_WINDOW_PARMS* = LPMCI_OVLY_WINDOW_PARMSA
|
||||||
type
|
type
|
||||||
TMCI_OVLY_WINDOW_PARMS* = MCI_OVLY_WINDOW_PARMSW
|
TMCI_OVLY_WINDOW_PARMS* = MCI_OVLY_WINDOW_PARMSW
|
||||||
MCI_OVLY_RECT_PARMS* = record
|
MCI_OVLY_RECT_PARMS* {.final.} = object
|
||||||
dwCallback*: DWORD
|
dwCallback*: DWORD
|
||||||
rc*: TRECT
|
rc*: TRECT
|
||||||
|
|
||||||
PMCI_OVLY_RECT_PARMS* = ptr MCI_OVLY_RECT_PARMS
|
PMCI_OVLY_RECT_PARMS* = ptr MCI_OVLY_RECT_PARMS
|
||||||
LPMCI_OVLY_RECT_PARMS* = ptr MCI_OVLY_RECT_PARMS
|
LPMCI_OVLY_RECT_PARMS* = ptr MCI_OVLY_RECT_PARMS
|
||||||
TMCI_OVLY_RECT_PARMS* = MCI_OVLY_RECT_PARMS
|
TMCI_OVLY_RECT_PARMS* = MCI_OVLY_RECT_PARMS
|
||||||
MCI_OVLY_SAVE_PARMSA* = record
|
MCI_OVLY_SAVE_PARMSA* {.final.} = object
|
||||||
dwCallback*: DWORD
|
dwCallback*: DWORD
|
||||||
lpfilename*: LPCSTR
|
lpfilename*: LPCSTR
|
||||||
rc*: TRECT
|
rc*: TRECT
|
||||||
|
|
@ -2190,7 +2190,7 @@ type
|
||||||
PMCI_OVLY_SAVE_PARMSA* = ptr MCI_OVLY_SAVE_PARMSA
|
PMCI_OVLY_SAVE_PARMSA* = ptr MCI_OVLY_SAVE_PARMSA
|
||||||
LPMCI_OVLY_SAVE_PARMSA* = ptr MCI_OVLY_SAVE_PARMSA
|
LPMCI_OVLY_SAVE_PARMSA* = ptr MCI_OVLY_SAVE_PARMSA
|
||||||
TMCI_OVLY_SAVE_PARMSA* = MCI_OVLY_SAVE_PARMSA
|
TMCI_OVLY_SAVE_PARMSA* = MCI_OVLY_SAVE_PARMSA
|
||||||
MCI_OVLY_SAVE_PARMSW* = record
|
MCI_OVLY_SAVE_PARMSW* {.final.} = object
|
||||||
dwCallback*: DWORD
|
dwCallback*: DWORD
|
||||||
lpfilename*: LPCWSTR
|
lpfilename*: LPCWSTR
|
||||||
rc*: TRECT
|
rc*: TRECT
|
||||||
|
|
@ -2211,7 +2211,7 @@ else:
|
||||||
LPMCI_OVLY_SAVE_PARMS* = LPMCI_OVLY_SAVE_PARMSA
|
LPMCI_OVLY_SAVE_PARMS* = LPMCI_OVLY_SAVE_PARMSA
|
||||||
type
|
type
|
||||||
TMCI_OVLY_SAVE_PARMS* = MCI_OVLY_SAVE_PARMS
|
TMCI_OVLY_SAVE_PARMS* = MCI_OVLY_SAVE_PARMS
|
||||||
MCI_OVLY_LOAD_PARMSA* = record
|
MCI_OVLY_LOAD_PARMSA* {.final.} = object
|
||||||
dwCallback*: DWORD
|
dwCallback*: DWORD
|
||||||
lpfilename*: LPCSTR
|
lpfilename*: LPCSTR
|
||||||
rc*: TRECT
|
rc*: TRECT
|
||||||
|
|
@ -2219,7 +2219,7 @@ type
|
||||||
PMCI_OVLY_LOAD_PARMSA* = ptr MCI_OVLY_LOAD_PARMSA
|
PMCI_OVLY_LOAD_PARMSA* = ptr MCI_OVLY_LOAD_PARMSA
|
||||||
LPMCI_OVLY_LOAD_PARMSA* = ptr MCI_OVLY_LOAD_PARMSA
|
LPMCI_OVLY_LOAD_PARMSA* = ptr MCI_OVLY_LOAD_PARMSA
|
||||||
TMCI_OVLY_LOAD_PARMSA* = MCI_OVLY_LOAD_PARMSA
|
TMCI_OVLY_LOAD_PARMSA* = MCI_OVLY_LOAD_PARMSA
|
||||||
MCI_OVLY_LOAD_PARMSW* = record
|
MCI_OVLY_LOAD_PARMSW* {.final.} = object
|
||||||
dwCallback*: DWORD
|
dwCallback*: DWORD
|
||||||
lpfilename*: LPCWSTR
|
lpfilename*: LPCWSTR
|
||||||
rc*: TRECT
|
rc*: TRECT
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@
|
||||||
#
|
#
|
||||||
# NetBIOS 3.0 interface unit
|
# NetBIOS 3.0 interface unit
|
||||||
|
|
||||||
# This unit contains the definitions for portable NetBIOS 3.0 support.
|
# This module contains the definitions for portable NetBIOS 3.0 support.
|
||||||
|
|
||||||
import # Data structure templates
|
import # Data structure templates
|
||||||
Windows
|
Windows
|
||||||
|
|
@ -20,7 +20,7 @@ const
|
||||||
type # Network Control Block
|
type # Network Control Block
|
||||||
PNCB* = ptr TNCB
|
PNCB* = ptr TNCB
|
||||||
TNCBPostProc* = proc (P: PNCB)
|
TNCBPostProc* = proc (P: PNCB)
|
||||||
TNCB* = record # Structure returned to the NCB command NCBASTAT is ADAPTER_STATUS followed
|
TNCB* {.final.} = object # Structure returned to the NCB command NCBASTAT is ADAPTER_STATUS followed
|
||||||
# by an array of NAME_BUFFER structures.
|
# by an array of NAME_BUFFER structures.
|
||||||
ncb_command*: Char # command code
|
ncb_command*: Char # command code
|
||||||
ncb_retcode*: Char # return code
|
ncb_retcode*: Char # return code
|
||||||
|
|
@ -42,7 +42,7 @@ type # Network Control Block
|
||||||
# completes
|
# completes
|
||||||
|
|
||||||
PAdapterStatus* = ptr TAdapterStatus
|
PAdapterStatus* = ptr TAdapterStatus
|
||||||
TAdapterStatus* = record
|
TAdapterStatus* {.final.} = object
|
||||||
adapter_address*: array[0..5, Char]
|
adapter_address*: array[0..5, Char]
|
||||||
rev_major*: Char
|
rev_major*: Char
|
||||||
reserved0*: Char
|
reserved0*: Char
|
||||||
|
|
@ -72,7 +72,7 @@ type # Network Control Block
|
||||||
name_count*: int16
|
name_count*: int16
|
||||||
|
|
||||||
PNameBuffer* = ptr TNameBuffer
|
PNameBuffer* = ptr TNameBuffer
|
||||||
TNameBuffer* = record
|
TNameBuffer* {.final.} = object
|
||||||
name*: array[0..NCBNAMSZ - 1, Char]
|
name*: array[0..NCBNAMSZ - 1, Char]
|
||||||
name_num*: Char
|
name_num*: Char
|
||||||
name_flags*: Char
|
name_flags*: Char
|
||||||
|
|
@ -93,14 +93,14 @@ type # Structure returned to the NCB command NCBSSTAT is SESSION_HEADER followed
|
||||||
# asterisk then an array of these structures is returned containing the
|
# asterisk then an array of these structures is returned containing the
|
||||||
# status for all names.
|
# status for all names.
|
||||||
PSessionHeader* = ptr TSessionHeader
|
PSessionHeader* = ptr TSessionHeader
|
||||||
TSessionHeader* = record
|
TSessionHeader* {.final.} = object
|
||||||
sess_name*: Char
|
sess_name*: Char
|
||||||
num_sess*: Char
|
num_sess*: Char
|
||||||
rcv_dg_outstanding*: Char
|
rcv_dg_outstanding*: Char
|
||||||
rcv_any_outstanding*: Char
|
rcv_any_outstanding*: Char
|
||||||
|
|
||||||
PSessionBuffer* = ptr TSessionBuffer
|
PSessionBuffer* = ptr TSessionBuffer
|
||||||
TSessionBuffer* = record
|
TSessionBuffer* {.final.} = object
|
||||||
lsn*: Char
|
lsn*: Char
|
||||||
state*: Char
|
state*: Char
|
||||||
local_name*: array[0..NCBNAMSZ - 1, Char]
|
local_name*: array[0..NCBNAMSZ - 1, Char]
|
||||||
|
|
@ -121,19 +121,19 @@ type # Structure returned to the NCB command NCBENUM.
|
||||||
# On a system containing lana's 0, 2 and 3, a structure with
|
# On a system containing lana's 0, 2 and 3, a structure with
|
||||||
# length =3, lana[0]=0, lana[1]=2 and lana[2]=3 will be returned.
|
# length =3, lana[0]=0, lana[1]=2 and lana[2]=3 will be returned.
|
||||||
PLanaEnum* = ptr TLanaEnum
|
PLanaEnum* = ptr TLanaEnum
|
||||||
TLanaEnum* = record # Structure returned to the NCB command NCBFINDNAME is FIND_NAME_HEADER followed
|
TLanaEnum* {.final.} = object # Structure returned to the NCB command NCBFINDNAME is FIND_NAME_HEADER followed
|
||||||
# by an array of FIND_NAME_BUFFER structures.
|
# by an array of FIND_NAME_BUFFER structures.
|
||||||
len*: Char # Number of valid entries in lana[]
|
len*: Char # Number of valid entries in lana[]
|
||||||
lana*: array[0..MAX_LANA, Char]
|
lana*: array[0..MAX_LANA, Char]
|
||||||
|
|
||||||
PFindNameHeader* = ptr TFindNameHeader
|
PFindNameHeader* = ptr TFindNameHeader
|
||||||
TFindNameHeader* = record
|
TFindNameHeader* {.final.} = object
|
||||||
node_count*: int16
|
node_count*: int16
|
||||||
reserved*: Char
|
reserved*: Char
|
||||||
unique_group*: Char
|
unique_group*: Char
|
||||||
|
|
||||||
PFindNameBuffer* = ptr TFindNameBuffer
|
PFindNameBuffer* = ptr TFindNameBuffer
|
||||||
TFindNameBuffer* = record # Structure provided with NCBACTION. The purpose of NCBACTION is to provide
|
TFindNameBuffer* {.final.} = object # Structure provided with NCBACTION. The purpose of NCBACTION is to provide
|
||||||
# transport specific extensions to netbios.
|
# transport specific extensions to netbios.
|
||||||
len*: Char
|
len*: Char
|
||||||
access_control*: Char
|
access_control*: Char
|
||||||
|
|
@ -143,7 +143,7 @@ type # Structure returned to the NCB command NCBENUM.
|
||||||
routing_info*: array[0..17, Char]
|
routing_info*: array[0..17, Char]
|
||||||
|
|
||||||
PActionHeader* = ptr TActionHeader
|
PActionHeader* = ptr TActionHeader
|
||||||
TActionHeader* = record
|
TActionHeader* {.final.} = object
|
||||||
transport_id*: int32
|
transport_id*: int32
|
||||||
action_code*: int16
|
action_code*: int16
|
||||||
reserved*: int16
|
reserved*: int16
|
||||||
|
|
|
||||||
|
|
@ -33,7 +33,7 @@ type
|
||||||
DWORD_PTR* = ptr DWORD
|
DWORD_PTR* = ptr DWORD
|
||||||
pHICON* = ptr HICON
|
pHICON* = ptr HICON
|
||||||
pBool* = ptr BOOL
|
pBool* = ptr BOOL
|
||||||
STARTUPINFOW* = record # a guess. Omission should get fixed in Windows.
|
STARTUPINFOW* {.final.} = object # a guess. Omission should get fixed in Windows.
|
||||||
cb*: DWORD
|
cb*: DWORD
|
||||||
lpReserved*: LPTSTR
|
lpReserved*: LPTSTR
|
||||||
lpDesktop*: LPTSTR
|
lpDesktop*: LPTSTR
|
||||||
|
|
@ -122,7 +122,7 @@ proc ExtractIcon*(hInst: HINST, lpszExeFileName: LPCWSTR, nIconIndex: UINT): HIC
|
||||||
stdcall, dynlib: "shell32.dll", importc: "ExtractIconW".}
|
stdcall, dynlib: "shell32.dll", importc: "ExtractIconW".}
|
||||||
# if(WINVER >= 0x0400)
|
# if(WINVER >= 0x0400)
|
||||||
type # init with sizeof(DRAGINFO)
|
type # init with sizeof(DRAGINFO)
|
||||||
DRAGINFOA* = record
|
DRAGINFOA* {.final.} = object
|
||||||
uSize*: UINT
|
uSize*: UINT
|
||||||
pt*: POINT
|
pt*: POINT
|
||||||
fNC*: BOOL
|
fNC*: BOOL
|
||||||
|
|
@ -131,7 +131,7 @@ type # init with sizeof(DRAGINFO)
|
||||||
|
|
||||||
TDRAGINFOA* = DRAGINFOA
|
TDRAGINFOA* = DRAGINFOA
|
||||||
LPDRAGINFOA* = ptr DRAGINFOA # init with sizeof(DRAGINFO)
|
LPDRAGINFOA* = ptr DRAGINFOA # init with sizeof(DRAGINFO)
|
||||||
DRAGINFOW* = record
|
DRAGINFOW* {.final.} = object
|
||||||
uSize*: UINT
|
uSize*: UINT
|
||||||
pt*: POINT
|
pt*: POINT
|
||||||
fNC*: BOOL
|
fNC*: BOOL
|
||||||
|
|
@ -178,7 +178,7 @@ const
|
||||||
ABE_BOTTOM* = 3
|
ABE_BOTTOM* = 3
|
||||||
|
|
||||||
type
|
type
|
||||||
AppBarData* = record
|
AppBarData* {.final.} = object
|
||||||
cbSize*: DWORD
|
cbSize*: DWORD
|
||||||
hWnd*: HWND
|
hWnd*: HWND
|
||||||
uCallbackMessage*: UINT
|
uCallbackMessage*: UINT
|
||||||
|
|
@ -286,7 +286,7 @@ type
|
||||||
# only used if FOF_SIMPLEPROGRESS
|
# only used if FOF_SIMPLEPROGRESS
|
||||||
|
|
||||||
type
|
type
|
||||||
SHFILEOPSTRUCTA* = record
|
SHFILEOPSTRUCTA* {.final.} = object
|
||||||
hwnd*: HWND
|
hwnd*: HWND
|
||||||
wFunc*: UINT
|
wFunc*: UINT
|
||||||
pFrom*: LPCSTR
|
pFrom*: LPCSTR
|
||||||
|
|
@ -298,7 +298,7 @@ type
|
||||||
|
|
||||||
TSHFILEOPSTRUCTA* = SHFILEOPSTRUCTA
|
TSHFILEOPSTRUCTA* = SHFILEOPSTRUCTA
|
||||||
LPSHFILEOPSTRUCTA* = ptr SHFILEOPSTRUCTA
|
LPSHFILEOPSTRUCTA* = ptr SHFILEOPSTRUCTA
|
||||||
SHFILEOPSTRUCTW* = record
|
SHFILEOPSTRUCTW* {.final.} = object
|
||||||
hwnd*: HWND
|
hwnd*: HWND
|
||||||
wFunc*: UINT
|
wFunc*: UINT
|
||||||
pFrom*: LPCWSTR
|
pFrom*: LPCWSTR
|
||||||
|
|
@ -332,7 +332,7 @@ proc SHFileOperation*(lpFileOp: LPSHFILEOPSTRUCTW): int32{.stdcall,
|
||||||
proc SHFreeNameMappings*(hNameMappings: THandle){.stdcall,
|
proc SHFreeNameMappings*(hNameMappings: THandle){.stdcall,
|
||||||
dynlib: "shell32.dll", importc: "SHFreeNameMappings".}
|
dynlib: "shell32.dll", importc: "SHFreeNameMappings".}
|
||||||
type
|
type
|
||||||
SHNAMEMAPPINGA* = record
|
SHNAMEMAPPINGA* {.final.} = object
|
||||||
pszOldPath*: LPSTR
|
pszOldPath*: LPSTR
|
||||||
pszNewPath*: LPSTR
|
pszNewPath*: LPSTR
|
||||||
cchOldPath*: int32
|
cchOldPath*: int32
|
||||||
|
|
@ -340,7 +340,7 @@ type
|
||||||
|
|
||||||
TSHNAMEMAPPINGA* = SHNAMEMAPPINGA
|
TSHNAMEMAPPINGA* = SHNAMEMAPPINGA
|
||||||
LPSHNAMEMAPPINGA* = ptr SHNAMEMAPPINGA
|
LPSHNAMEMAPPINGA* = ptr SHNAMEMAPPINGA
|
||||||
SHNAMEMAPPINGW* = record
|
SHNAMEMAPPINGW* {.final.} = object
|
||||||
pszOldPath*: LPWSTR
|
pszOldPath*: LPWSTR
|
||||||
pszNewPath*: LPWSTR
|
pszNewPath*: LPWSTR
|
||||||
cchOldPath*: int32
|
cchOldPath*: int32
|
||||||
|
|
@ -404,7 +404,7 @@ const
|
||||||
# (_WIN32_IE >= 0x560)
|
# (_WIN32_IE >= 0x560)
|
||||||
|
|
||||||
type
|
type
|
||||||
SHELLEXECUTEINFOA* = record
|
SHELLEXECUTEINFOA* {.final.} = object
|
||||||
cbSize*: DWORD
|
cbSize*: DWORD
|
||||||
fMask*: ULONG
|
fMask*: ULONG
|
||||||
hwnd*: HWND
|
hwnd*: HWND
|
||||||
|
|
@ -423,7 +423,7 @@ type
|
||||||
|
|
||||||
TSHELLEXECUTEINFOA* = SHELLEXECUTEINFOA
|
TSHELLEXECUTEINFOA* = SHELLEXECUTEINFOA
|
||||||
LPSHELLEXECUTEINFOA* = ptr SHELLEXECUTEINFOA
|
LPSHELLEXECUTEINFOA* = ptr SHELLEXECUTEINFOA
|
||||||
SHELLEXECUTEINFOW* = record
|
SHELLEXECUTEINFOW* {.final.} = object
|
||||||
cbSize*: DWORD
|
cbSize*: DWORD
|
||||||
fMask*: ULONG
|
fMask*: ULONG
|
||||||
hwnd*: HWND
|
hwnd*: HWND
|
||||||
|
|
@ -474,7 +474,7 @@ proc WinExecError*(HWND: hwnd, error: int32, lpstrFileName: LPCWSTR,
|
||||||
lpstrTitle: LPCWSTR){.stdcall, dynlib: "shell32.dll",
|
lpstrTitle: LPCWSTR){.stdcall, dynlib: "shell32.dll",
|
||||||
importc: "WinExecErrorW".}
|
importc: "WinExecErrorW".}
|
||||||
type
|
type
|
||||||
SHCREATEPROCESSINFOW* = record
|
SHCREATEPROCESSINFOW* {.final.} = object
|
||||||
cbSize*: DWORD
|
cbSize*: DWORD
|
||||||
fMask*: ULONG
|
fMask*: ULONG
|
||||||
hwnd*: HWND
|
hwnd*: HWND
|
||||||
|
|
@ -502,7 +502,7 @@ proc SHCreateProcessAsUserW*(pscpi: PSHCREATEPROCESSINFOW): Bool{.stdcall,
|
||||||
#
|
#
|
||||||
# struct for query recycle bin info
|
# struct for query recycle bin info
|
||||||
type
|
type
|
||||||
SHQUERYRBINFO* = record
|
SHQUERYRBINFO* {.final.} = object
|
||||||
cbSize*: DWORD
|
cbSize*: DWORD
|
||||||
i64Size*: int64
|
i64Size*: int64
|
||||||
i64NumItems*: int64
|
i64NumItems*: int64
|
||||||
|
|
@ -538,7 +538,7 @@ proc SHEmptyRecycleBin*(hwnd: HWND, pszRootPath: LPCWSTR, dwFlags: DWORD): HRESU
|
||||||
# Tray notification definitions
|
# Tray notification definitions
|
||||||
#
|
#
|
||||||
type
|
type
|
||||||
NOTIFYICONDATAA* = record
|
NOTIFYICONDATAA* {.final.} = object
|
||||||
cbSize*: DWORD
|
cbSize*: DWORD
|
||||||
hWnd*: HWND
|
hWnd*: HWND
|
||||||
uID*: UINT
|
uID*: UINT
|
||||||
|
|
@ -556,7 +556,7 @@ type
|
||||||
|
|
||||||
TNOTIFYICONDATAA* = NOTIFYICONDATAA
|
TNOTIFYICONDATAA* = NOTIFYICONDATAA
|
||||||
PNOTIFYICONDATAA* = ptr NOTIFYICONDATAA
|
PNOTIFYICONDATAA* = ptr NOTIFYICONDATAA
|
||||||
NOTIFYICONDATAW* = record
|
NOTIFYICONDATAW* {.final.} = object
|
||||||
cbSize*: DWORD
|
cbSize*: DWORD
|
||||||
hWnd*: HWND
|
hWnd*: HWND
|
||||||
uID*: UINT
|
uID*: UINT
|
||||||
|
|
@ -645,7 +645,7 @@ proc Shell_NotifyIcon*(dwMessage: Dword, lpData: PNOTIFYICONDATAW): Bool{.
|
||||||
# out: display name (or path)
|
# out: display name (or path)
|
||||||
# out: type name
|
# out: type name
|
||||||
type
|
type
|
||||||
SHFILEINFOA* = record
|
SHFILEINFOA* {.final.} = object
|
||||||
hIcon*: HICON # out: icon
|
hIcon*: HICON # out: icon
|
||||||
iIcon*: int32 # out: icon index
|
iIcon*: int32 # out: icon index
|
||||||
dwAttributes*: DWORD # out: SFGAO_ flags
|
dwAttributes*: DWORD # out: SFGAO_ flags
|
||||||
|
|
@ -654,7 +654,7 @@ type
|
||||||
|
|
||||||
TSHFILEINFOA* = SHFILEINFOA
|
TSHFILEINFOA* = SHFILEINFOA
|
||||||
pSHFILEINFOA* = ptr SHFILEINFOA
|
pSHFILEINFOA* = ptr SHFILEINFOA
|
||||||
SHFILEINFOW* = record
|
SHFILEINFOW* {.final.} = object
|
||||||
hIcon*: HICON # out: icon
|
hIcon*: HICON # out: icon
|
||||||
iIcon*: int32 # out: icon index
|
iIcon*: int32 # out: icon index
|
||||||
dwAttributes*: DWORD # out: SFGAO_ flags
|
dwAttributes*: DWORD # out: SFGAO_ flags
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load diff
406
nim/ast.pas
406
nim/ast.pas
|
|
@ -64,6 +64,135 @@ for key, val in enums.iteritems():
|
||||||
cog.out(a)
|
cog.out(a)
|
||||||
cog.out(b)
|
cog.out(b)
|
||||||
]]]*)
|
]]]*)
|
||||||
|
type
|
||||||
|
TNodeKind = (
|
||||||
|
nkNone, nkEmpty, nkIdent, nkSym,
|
||||||
|
nkType, nkCharLit, nkIntLit, nkInt8Lit,
|
||||||
|
nkInt16Lit, nkInt32Lit, nkInt64Lit, nkFloatLit,
|
||||||
|
nkFloat32Lit, nkFloat64Lit, nkStrLit, nkRStrLit,
|
||||||
|
nkTripleStrLit, nkMetaNode, nkNilLit, nkDotCall,
|
||||||
|
nkCommand, nkCall, nkGenericCall, nkExplicitTypeListCall,
|
||||||
|
nkExprEqExpr, nkExprColonExpr, nkIdentDefs, nkInfix,
|
||||||
|
nkPrefix, nkPostfix, nkPar, nkCurly,
|
||||||
|
nkBracket, nkBracketExpr, nkPragmaExpr, nkRange,
|
||||||
|
nkDotExpr, nkCheckedFieldExpr, nkDerefExpr, nkIfExpr,
|
||||||
|
nkElifExpr, nkElseExpr, nkLambda, nkAccQuoted,
|
||||||
|
nkHeaderQuoted, nkTableConstr, nkQualified, nkHiddenStdConv,
|
||||||
|
nkHiddenSubConv, nkHiddenCallConv, nkConv, nkCast,
|
||||||
|
nkAddr, nkHiddenAddr, nkHiddenDeref, nkObjDownConv,
|
||||||
|
nkObjUpConv, nkChckRangeF, nkChckRange64, nkChckRange,
|
||||||
|
nkStringToCString, nkCStringToString, nkPassAsOpenArray, nkAsgn,
|
||||||
|
nkDefaultTypeParam, nkGenericParams, nkFormalParams, nkOfInherit,
|
||||||
|
nkModule, nkProcDef, nkConverterDef, nkMacroDef,
|
||||||
|
nkTemplateDef, nkIteratorDef, nkOfBranch, nkElifBranch,
|
||||||
|
nkExceptBranch, nkElse, nkMacroStmt, nkAsmStmt,
|
||||||
|
nkPragma, nkIfStmt, nkWhenStmt, nkForStmt,
|
||||||
|
nkWhileStmt, nkCaseStmt, nkVarSection, nkConstSection,
|
||||||
|
nkConstDef, nkTypeSection, nkTypeDef, nkYieldStmt,
|
||||||
|
nkTryStmt, nkFinally, nkRaiseStmt, nkReturnStmt,
|
||||||
|
nkBreakStmt, nkContinueStmt, nkBlockStmt, nkDiscardStmt,
|
||||||
|
nkStmtList, nkImportStmt, nkFromStmt, nkImportAs,
|
||||||
|
nkIncludeStmt, nkAccessStmt, nkCommentStmt, nkStmtListExpr,
|
||||||
|
nkBlockExpr, nkVm, nkTypeOfExpr, nkObjectTy,
|
||||||
|
nkTupleTy, nkRecList, nkRecCase, nkRecWhen,
|
||||||
|
nkRefTy, nkPtrTy, nkVarTy, nkProcTy,
|
||||||
|
nkEnumTy, nkEnumFieldDef, nkReturnToken);
|
||||||
|
TNodeKinds = set of TNodeKind;
|
||||||
|
const
|
||||||
|
NodeKindToStr: array [TNodeKind] of string = (
|
||||||
|
'nkNone', 'nkEmpty', 'nkIdent', 'nkSym',
|
||||||
|
'nkType', 'nkCharLit', 'nkIntLit', 'nkInt8Lit',
|
||||||
|
'nkInt16Lit', 'nkInt32Lit', 'nkInt64Lit', 'nkFloatLit',
|
||||||
|
'nkFloat32Lit', 'nkFloat64Lit', 'nkStrLit', 'nkRStrLit',
|
||||||
|
'nkTripleStrLit', 'nkMetaNode', 'nkNilLit', 'nkDotCall',
|
||||||
|
'nkCommand', 'nkCall', 'nkGenericCall', 'nkExplicitTypeListCall',
|
||||||
|
'nkExprEqExpr', 'nkExprColonExpr', 'nkIdentDefs', 'nkInfix',
|
||||||
|
'nkPrefix', 'nkPostfix', 'nkPar', 'nkCurly',
|
||||||
|
'nkBracket', 'nkBracketExpr', 'nkPragmaExpr', 'nkRange',
|
||||||
|
'nkDotExpr', 'nkCheckedFieldExpr', 'nkDerefExpr', 'nkIfExpr',
|
||||||
|
'nkElifExpr', 'nkElseExpr', 'nkLambda', 'nkAccQuoted',
|
||||||
|
'nkHeaderQuoted', 'nkTableConstr', 'nkQualified', 'nkHiddenStdConv',
|
||||||
|
'nkHiddenSubConv', 'nkHiddenCallConv', 'nkConv', 'nkCast',
|
||||||
|
'nkAddr', 'nkHiddenAddr', 'nkHiddenDeref', 'nkObjDownConv',
|
||||||
|
'nkObjUpConv', 'nkChckRangeF', 'nkChckRange64', 'nkChckRange',
|
||||||
|
'nkStringToCString', 'nkCStringToString', 'nkPassAsOpenArray', 'nkAsgn',
|
||||||
|
'nkDefaultTypeParam', 'nkGenericParams', 'nkFormalParams', 'nkOfInherit',
|
||||||
|
'nkModule', 'nkProcDef', 'nkConverterDef', 'nkMacroDef',
|
||||||
|
'nkTemplateDef', 'nkIteratorDef', 'nkOfBranch', 'nkElifBranch',
|
||||||
|
'nkExceptBranch', 'nkElse', 'nkMacroStmt', 'nkAsmStmt',
|
||||||
|
'nkPragma', 'nkIfStmt', 'nkWhenStmt', 'nkForStmt',
|
||||||
|
'nkWhileStmt', 'nkCaseStmt', 'nkVarSection', 'nkConstSection',
|
||||||
|
'nkConstDef', 'nkTypeSection', 'nkTypeDef', 'nkYieldStmt',
|
||||||
|
'nkTryStmt', 'nkFinally', 'nkRaiseStmt', 'nkReturnStmt',
|
||||||
|
'nkBreakStmt', 'nkContinueStmt', 'nkBlockStmt', 'nkDiscardStmt',
|
||||||
|
'nkStmtList', 'nkImportStmt', 'nkFromStmt', 'nkImportAs',
|
||||||
|
'nkIncludeStmt', 'nkAccessStmt', 'nkCommentStmt', 'nkStmtListExpr',
|
||||||
|
'nkBlockExpr', 'nkVm', 'nkTypeOfExpr', 'nkObjectTy',
|
||||||
|
'nkTupleTy', 'nkRecList', 'nkRecCase', 'nkRecWhen',
|
||||||
|
'nkRefTy', 'nkPtrTy', 'nkVarTy', 'nkProcTy',
|
||||||
|
'nkEnumTy', 'nkEnumFieldDef', 'nkReturnToken');
|
||||||
|
type
|
||||||
|
TSymFlag = (
|
||||||
|
sfTypeCheck, sfForward, sfImportc, sfExportc,
|
||||||
|
sfVolatile, sfUsed, sfWrite, sfRegister,
|
||||||
|
sfPure, sfCodeGenerated, sfPrivate, sfGlobal,
|
||||||
|
sfResult, sfNoSideEffect, sfMainModule, sfSystemModule,
|
||||||
|
sfNoReturn, sfAddrTaken, sfInInterface, sfNoStatic,
|
||||||
|
sfCompilerProc, sfCppMethod, sfDiscriminant, sfDeprecated,
|
||||||
|
sfInClosure, sfIsCopy, sfStar, sfMinus);
|
||||||
|
TSymFlags = set of TSymFlag;
|
||||||
|
const
|
||||||
|
SymFlagToStr: array [TSymFlag] of string = (
|
||||||
|
'sfTypeCheck', 'sfForward', 'sfImportc', 'sfExportc',
|
||||||
|
'sfVolatile', 'sfUsed', 'sfWrite', 'sfRegister',
|
||||||
|
'sfPure', 'sfCodeGenerated', 'sfPrivate', 'sfGlobal',
|
||||||
|
'sfResult', 'sfNoSideEffect', 'sfMainModule', 'sfSystemModule',
|
||||||
|
'sfNoReturn', 'sfAddrTaken', 'sfInInterface', 'sfNoStatic',
|
||||||
|
'sfCompilerProc', 'sfCppMethod', 'sfDiscriminant', 'sfDeprecated',
|
||||||
|
'sfInClosure', 'sfIsCopy', 'sfStar', 'sfMinus');
|
||||||
|
type
|
||||||
|
TTypeKind = (
|
||||||
|
tyNone, tyBool, tyChar, tyEmptySet,
|
||||||
|
tyArrayConstr, tyNil, tyGeneric, tyGenericInst,
|
||||||
|
tyGenericParam, tyEnum, tyAnyEnum, tyArray,
|
||||||
|
tyObject, tyTuple, tySet, tyRange,
|
||||||
|
tyPtr, tyRef, tyVar, tySequence,
|
||||||
|
tyProc, tyPointer, tyOpenArray, tyString,
|
||||||
|
tyCString, tyForward, tyInt, tyInt8,
|
||||||
|
tyInt16, tyInt32, tyInt64, tyFloat,
|
||||||
|
tyFloat32, tyFloat64, tyFloat128);
|
||||||
|
TTypeKinds = set of TTypeKind;
|
||||||
|
const
|
||||||
|
TypeKindToStr: array [TTypeKind] of string = (
|
||||||
|
'tyNone', 'tyBool', 'tyChar', 'tyEmptySet',
|
||||||
|
'tyArrayConstr', 'tyNil', 'tyGeneric', 'tyGenericInst',
|
||||||
|
'tyGenericParam', 'tyEnum', 'tyAnyEnum', 'tyArray',
|
||||||
|
'tyObject', 'tyTuple', 'tySet', 'tyRange',
|
||||||
|
'tyPtr', 'tyRef', 'tyVar', 'tySequence',
|
||||||
|
'tyProc', 'tyPointer', 'tyOpenArray', 'tyString',
|
||||||
|
'tyCString', 'tyForward', 'tyInt', 'tyInt8',
|
||||||
|
'tyInt16', 'tyInt32', 'tyInt64', 'tyFloat',
|
||||||
|
'tyFloat32', 'tyFloat64', 'tyFloat128');
|
||||||
|
type
|
||||||
|
TNodeFlag = (
|
||||||
|
nfNone, nfBase2, nfBase8, nfBase16,
|
||||||
|
nfAllConst);
|
||||||
|
TNodeFlags = set of TNodeFlag;
|
||||||
|
const
|
||||||
|
NodeFlagToStr: array [TNodeFlag] of string = (
|
||||||
|
'nfNone', 'nfBase2', 'nfBase8', 'nfBase16',
|
||||||
|
'nfAllConst');
|
||||||
|
type
|
||||||
|
TTypeFlag = (
|
||||||
|
tfIsDistinct, tfGeneric, tfExternal, tfImported,
|
||||||
|
tfInfoGenerated, tfSemChecked, tfHasOutParams, tfEnumHasWholes,
|
||||||
|
tfVarargs, tfFinal);
|
||||||
|
TTypeFlags = set of TTypeFlag;
|
||||||
|
const
|
||||||
|
TypeFlagToStr: array [TTypeFlag] of string = (
|
||||||
|
'tfIsDistinct', 'tfGeneric', 'tfExternal', 'tfImported',
|
||||||
|
'tfInfoGenerated', 'tfSemChecked', 'tfHasOutParams', 'tfEnumHasWholes',
|
||||||
|
'tfVarargs', 'tfFinal');
|
||||||
type
|
type
|
||||||
TSymKind = (
|
TSymKind = (
|
||||||
skUnknownSym, skConditional, skDynLib, skParam,
|
skUnknownSym, skConditional, skDynLib, skParam,
|
||||||
|
|
@ -79,126 +208,6 @@ const
|
||||||
'skVar', 'skProc', 'skIterator', 'skConverter',
|
'skVar', 'skProc', 'skIterator', 'skConverter',
|
||||||
'skMacro', 'skTemplate', 'skField', 'skEnumField',
|
'skMacro', 'skTemplate', 'skField', 'skEnumField',
|
||||||
'skForVar', 'skModule', 'skLabel');
|
'skForVar', 'skModule', 'skLabel');
|
||||||
type
|
|
||||||
TNodeKind = (
|
|
||||||
nkNone, nkEmpty, nkIdent, nkSym,
|
|
||||||
nkType, nkCharLit, nkRCharLit, nkIntLit,
|
|
||||||
nkInt8Lit, nkInt16Lit, nkInt32Lit, nkInt64Lit,
|
|
||||||
nkFloatLit, nkFloat32Lit, nkFloat64Lit, nkStrLit,
|
|
||||||
nkRStrLit, nkTripleStrLit, nkNilLit, nkDotCall,
|
|
||||||
nkCommand, nkCall, nkGenericCall, nkExplicitTypeListCall,
|
|
||||||
nkExprEqExpr, nkExprColonExpr, nkIdentDefs, nkInfix,
|
|
||||||
nkPrefix, nkPostfix, nkPar, nkCurly,
|
|
||||||
nkBracket, nkBracketExpr, nkPragmaExpr, nkRange,
|
|
||||||
nkDotExpr, nkCheckedFieldExpr, nkDerefExpr, nkIfExpr,
|
|
||||||
nkElifExpr, nkElseExpr, nkLambda, nkAccQuoted,
|
|
||||||
nkHeaderQuoted, nkSetConstr, nkConstSetConstr, nkArrayConstr,
|
|
||||||
nkConstArrayConstr, nkRecordConstr, nkConstRecordConstr, nkTableConstr,
|
|
||||||
nkConstTableConstr, nkQualified, nkHiddenStdConv, nkHiddenSubConv,
|
|
||||||
nkHiddenCallConv, nkConv, nkCast, nkAddr,
|
|
||||||
nkAsgn, nkDefaultTypeParam, nkGenericParams, nkFormalParams,
|
|
||||||
nkOfInherit, nkModule, nkProcDef, nkConverterDef,
|
|
||||||
nkMacroDef, nkTemplateDef, nkIteratorDef, nkOfBranch,
|
|
||||||
nkElifBranch, nkExceptBranch, nkElse, nkMacroStmt,
|
|
||||||
nkAsmStmt, nkPragma, nkIfStmt, nkWhenStmt,
|
|
||||||
nkForStmt, nkWhileStmt, nkCaseStmt, nkVarSection,
|
|
||||||
nkConstSection, nkConstDef, nkTypeSection, nkTypeDef,
|
|
||||||
nkYieldStmt, nkTryStmt, nkFinally, nkRaiseStmt,
|
|
||||||
nkReturnStmt, nkBreakStmt, nkContinueStmt, nkBlockStmt,
|
|
||||||
nkGotoStmt, nkDiscardStmt, nkStmtList, nkImportStmt,
|
|
||||||
nkFromStmt, nkImportAs, nkIncludeStmt, nkAccessStmt,
|
|
||||||
nkCommentStmt, nkStmtListExpr, nkBlockExpr, nkVm,
|
|
||||||
nkTypeOfExpr, nkRecordTy, nkObjectTy, nkRecList,
|
|
||||||
nkRecCase, nkRecWhen, nkRefTy, nkPtrTy,
|
|
||||||
nkVarTy, nkProcTy, nkEnumTy, nkEnumFieldDef);
|
|
||||||
TNodeKinds = set of TNodeKind;
|
|
||||||
const
|
|
||||||
NodeKindToStr: array [TNodeKind] of string = (
|
|
||||||
'nkNone', 'nkEmpty', 'nkIdent', 'nkSym',
|
|
||||||
'nkType', 'nkCharLit', 'nkRCharLit', 'nkIntLit',
|
|
||||||
'nkInt8Lit', 'nkInt16Lit', 'nkInt32Lit', 'nkInt64Lit',
|
|
||||||
'nkFloatLit', 'nkFloat32Lit', 'nkFloat64Lit', 'nkStrLit',
|
|
||||||
'nkRStrLit', 'nkTripleStrLit', 'nkNilLit', 'nkDotCall',
|
|
||||||
'nkCommand', 'nkCall', 'nkGenericCall', 'nkExplicitTypeListCall',
|
|
||||||
'nkExprEqExpr', 'nkExprColonExpr', 'nkIdentDefs', 'nkInfix',
|
|
||||||
'nkPrefix', 'nkPostfix', 'nkPar', 'nkCurly',
|
|
||||||
'nkBracket', 'nkBracketExpr', 'nkPragmaExpr', 'nkRange',
|
|
||||||
'nkDotExpr', 'nkCheckedFieldExpr', 'nkDerefExpr', 'nkIfExpr',
|
|
||||||
'nkElifExpr', 'nkElseExpr', 'nkLambda', 'nkAccQuoted',
|
|
||||||
'nkHeaderQuoted', 'nkSetConstr', 'nkConstSetConstr', 'nkArrayConstr',
|
|
||||||
'nkConstArrayConstr', 'nkRecordConstr', 'nkConstRecordConstr', 'nkTableConstr',
|
|
||||||
'nkConstTableConstr', 'nkQualified', 'nkHiddenStdConv', 'nkHiddenSubConv',
|
|
||||||
'nkHiddenCallConv', 'nkConv', 'nkCast', 'nkAddr',
|
|
||||||
'nkAsgn', 'nkDefaultTypeParam', 'nkGenericParams', 'nkFormalParams',
|
|
||||||
'nkOfInherit', 'nkModule', 'nkProcDef', 'nkConverterDef',
|
|
||||||
'nkMacroDef', 'nkTemplateDef', 'nkIteratorDef', 'nkOfBranch',
|
|
||||||
'nkElifBranch', 'nkExceptBranch', 'nkElse', 'nkMacroStmt',
|
|
||||||
'nkAsmStmt', 'nkPragma', 'nkIfStmt', 'nkWhenStmt',
|
|
||||||
'nkForStmt', 'nkWhileStmt', 'nkCaseStmt', 'nkVarSection',
|
|
||||||
'nkConstSection', 'nkConstDef', 'nkTypeSection', 'nkTypeDef',
|
|
||||||
'nkYieldStmt', 'nkTryStmt', 'nkFinally', 'nkRaiseStmt',
|
|
||||||
'nkReturnStmt', 'nkBreakStmt', 'nkContinueStmt', 'nkBlockStmt',
|
|
||||||
'nkGotoStmt', 'nkDiscardStmt', 'nkStmtList', 'nkImportStmt',
|
|
||||||
'nkFromStmt', 'nkImportAs', 'nkIncludeStmt', 'nkAccessStmt',
|
|
||||||
'nkCommentStmt', 'nkStmtListExpr', 'nkBlockExpr', 'nkVm',
|
|
||||||
'nkTypeOfExpr', 'nkRecordTy', 'nkObjectTy', 'nkRecList',
|
|
||||||
'nkRecCase', 'nkRecWhen', 'nkRefTy', 'nkPtrTy',
|
|
||||||
'nkVarTy', 'nkProcTy', 'nkEnumTy', 'nkEnumFieldDef');
|
|
||||||
type
|
|
||||||
TSymFlag = (
|
|
||||||
sfGeneric, sfForward, sfImportc, sfExportc,
|
|
||||||
sfVolatile, sfUsed, sfWrite, sfRegister,
|
|
||||||
sfPure, sfCodeGenerated, sfPrivate, sfGlobal,
|
|
||||||
sfResult, sfNoSideEffect, sfMainModule, sfSystemModule,
|
|
||||||
sfNoReturn, sfReturnsNew, sfInInterface, sfNoStatic,
|
|
||||||
sfCompilerProc, sfCppMethod, sfDiscriminant, sfDeprecated,
|
|
||||||
sfInClosure, sfIsCopy, sfStar, sfMinus);
|
|
||||||
TSymFlags = set of TSymFlag;
|
|
||||||
const
|
|
||||||
SymFlagToStr: array [TSymFlag] of string = (
|
|
||||||
'sfGeneric', 'sfForward', 'sfImportc', 'sfExportc',
|
|
||||||
'sfVolatile', 'sfUsed', 'sfWrite', 'sfRegister',
|
|
||||||
'sfPure', 'sfCodeGenerated', 'sfPrivate', 'sfGlobal',
|
|
||||||
'sfResult', 'sfNoSideEffect', 'sfMainModule', 'sfSystemModule',
|
|
||||||
'sfNoReturn', 'sfReturnsNew', 'sfInInterface', 'sfNoStatic',
|
|
||||||
'sfCompilerProc', 'sfCppMethod', 'sfDiscriminant', 'sfDeprecated',
|
|
||||||
'sfInClosure', 'sfIsCopy', 'sfStar', 'sfMinus');
|
|
||||||
type
|
|
||||||
TTypeKind = (
|
|
||||||
tyNone, tyBool, tyChar, tyEmptySet,
|
|
||||||
tyArrayConstr, tyNil, tyRecordConstr, tyGeneric,
|
|
||||||
tyGenericInst, tyGenericParam, tyEnum, tyAnyEnum,
|
|
||||||
tyArray, tyRecord, tyObject, tyTuple,
|
|
||||||
tySet, tyRange, tyPtr, tyRef,
|
|
||||||
tyVar, tySequence, tyProc, tyPointer,
|
|
||||||
tyOpenArray, tyString, tyCString, tyForward,
|
|
||||||
tyInt, tyInt8, tyInt16, tyInt32,
|
|
||||||
tyInt64, tyFloat, tyFloat32, tyFloat64,
|
|
||||||
tyFloat128);
|
|
||||||
TTypeKinds = set of TTypeKind;
|
|
||||||
const
|
|
||||||
TypeKindToStr: array [TTypeKind] of string = (
|
|
||||||
'tyNone', 'tyBool', 'tyChar', 'tyEmptySet',
|
|
||||||
'tyArrayConstr', 'tyNil', 'tyRecordConstr', 'tyGeneric',
|
|
||||||
'tyGenericInst', 'tyGenericParam', 'tyEnum', 'tyAnyEnum',
|
|
||||||
'tyArray', 'tyRecord', 'tyObject', 'tyTuple',
|
|
||||||
'tySet', 'tyRange', 'tyPtr', 'tyRef',
|
|
||||||
'tyVar', 'tySequence', 'tyProc', 'tyPointer',
|
|
||||||
'tyOpenArray', 'tyString', 'tyCString', 'tyForward',
|
|
||||||
'tyInt', 'tyInt8', 'tyInt16', 'tyInt32',
|
|
||||||
'tyInt64', 'tyFloat', 'tyFloat32', 'tyFloat64',
|
|
||||||
'tyFloat128');
|
|
||||||
type
|
|
||||||
TTypeFlag = (
|
|
||||||
tfIsDistinct, tfGeneric, tfExternal, tfImported,
|
|
||||||
tfInfoGenerated, tfSemChecked, tfHasOutParams, tfEnumHasWholes,
|
|
||||||
tfVarargs, tfAssignable);
|
|
||||||
TTypeFlags = set of TTypeFlag;
|
|
||||||
const
|
|
||||||
TypeFlagToStr: array [TTypeFlag] of string = (
|
|
||||||
'tfIsDistinct', 'tfGeneric', 'tfExternal', 'tfImported',
|
|
||||||
'tfInfoGenerated', 'tfSemChecked', 'tfHasOutParams', 'tfEnumHasWholes',
|
|
||||||
'tfVarargs', 'tfAssignable');
|
|
||||||
{[[[end]]]}
|
{[[[end]]]}
|
||||||
|
|
||||||
type
|
type
|
||||||
|
|
@ -228,20 +237,28 @@ type
|
||||||
mEqProc, mEqUntracedRef, mLePtr, mLtPtr, mEqCString, mXor,
|
mEqProc, mEqUntracedRef, mLePtr, mLtPtr, mEqCString, mXor,
|
||||||
mUnaryMinusI, mUnaryMinusI64, mAbsI, mAbsI64, mNot, mUnaryPlusI,
|
mUnaryMinusI, mUnaryMinusI64, mAbsI, mAbsI64, mNot, mUnaryPlusI,
|
||||||
mBitnotI, mUnaryPlusI64, mBitnotI64, mUnaryPlusF64, mUnaryMinusF64, mAbsF64,
|
mBitnotI, mUnaryPlusI64, mBitnotI64, mUnaryPlusF64, mUnaryMinusF64, mAbsF64,
|
||||||
mZe, mZe64, mToU8, mToU16, mToU32, mToFloat,
|
mZe8ToI, mZe8ToI64, mZe16ToI, mZe16ToI64, mZe32ToI64, mZeIToI64,
|
||||||
mToBiggestFloat, mToInt, mToBiggestInt, mAnd, mOr, mEqStr,
|
mToU8, mToU16, mToU32, mToFloat, mToBiggestFloat, mToInt,
|
||||||
mLeStr, mLtStr, mEqSet, mLeSet, mLtSet, mMulSet,
|
mToBiggestInt, mCharToStr, mBoolToStr, mIntToStr, mInt64ToStr, mFloatToStr,
|
||||||
mPlusSet, mMinusSet, mSymDiffSet, mConStrStr, mConArrArr, mConArrT,
|
mCStrToStr, mStrToStr, mAnd, mOr, mEqStr, mLeStr,
|
||||||
mConTArr, mConTT, mSlice, mAppendStrCh, mAppendStrStr, mAppendSeqElem,
|
mLtStr, mEqSet, mLeSet, mLtSet, mMulSet, mPlusSet,
|
||||||
mAppendSeqSeq, mInRange, mInSet, mIs, mAsgn, mRepr,
|
mMinusSet, mSymDiffSet, mConStrStr, mConArrArr, mConArrT, mConTArr,
|
||||||
mExit, mSetLengthStr, mSetLengthSeq, mAssert, mSwap, mArray,
|
mConTT, mSlice, mAppendStrCh, mAppendStrStr, mAppendSeqElem, mAppendSeqSeq,
|
||||||
mOpenArray, mRange, mTuple, mSet, mSeq, mCompileDate,
|
mInRange, mInSet, mIs, mAsgn, mRepr, mExit,
|
||||||
mCompileTime, mNimrodVersion, mNimrodMajor, mNimrodMinor, mNimrodPatch, mCpuEndian
|
mSetLengthStr, mSetLengthSeq, mAssert, mSwap, mIsNil, mArray,
|
||||||
|
mOpenArray, mRange, mSet, mSeq, mCompileDate, mCompileTime,
|
||||||
|
mNimrodVersion, mNimrodMajor, mNimrodMinor, mNimrodPatch, mCpuEndian, mNaN,
|
||||||
|
mInf, mNegInf, mNLen, mNChild, mNSetChild, mNAdd,
|
||||||
|
mNAddMultiple, mNDel, mNKind, mNIntVal, mNFloatVal, mNSymbol,
|
||||||
|
mNIdent, mNGetType, mNStrVal, mNSetIntVal, mNSetFloatVal, mNSetSymbol,
|
||||||
|
mNSetIdent, mNSetType, mNSetStrVal, mNNewNimNode, mNCopyNimNode, mNCopyNimTree,
|
||||||
|
mStrToIdent, mIdentToStr, mEqIdent, mNHint, mNWarning, mNError
|
||||||
//[[[end]]]
|
//[[[end]]]
|
||||||
);
|
);
|
||||||
|
|
||||||
type
|
type
|
||||||
PNode = ^TNode;
|
PNode = ^TNode;
|
||||||
|
PNodePtr = ^{@ptr}PNode;
|
||||||
TNodeSeq = array of PNode;
|
TNodeSeq = array of PNode;
|
||||||
|
|
||||||
PType = ^TType;
|
PType = ^TType;
|
||||||
|
|
@ -254,22 +271,22 @@ type
|
||||||
comment: string;
|
comment: string;
|
||||||
sons: TNodeSeq; // else!
|
sons: TNodeSeq; // else!
|
||||||
info: TLineInfo;
|
info: TLineInfo;
|
||||||
base: TNumericalBase; // only valid for int or float literals
|
flags: TNodeFlags;
|
||||||
case Kind: TNodeKind of
|
case Kind: TNodeKind of
|
||||||
nkCharLit, nkRCharLit,
|
nkCharLit, nkIntLit, nkInt8Lit, nkInt16Lit, nkInt32Lit, nkInt64Lit:
|
||||||
nkIntLit, nkInt8Lit, nkInt16Lit, nkInt32Lit, nkInt64Lit:
|
|
||||||
(intVal: biggestInt);
|
(intVal: biggestInt);
|
||||||
nkFloatLit, nkFloat32Lit, nkFloat64Lit:
|
nkFloatLit, nkFloat32Lit, nkFloat64Lit:
|
||||||
(floatVal: biggestFloat);
|
(floatVal: biggestFloat);
|
||||||
nkSym: (sym: PSym);
|
nkSym: (sym: PSym);
|
||||||
nkIdent: (ident: PIdent);
|
nkIdent: (ident: PIdent);
|
||||||
|
nkMetaNode: (nodePtr: PNodePtr);
|
||||||
end;
|
end;
|
||||||
{@emit
|
{@emit
|
||||||
record // keep this below 32 bytes; otherwise the AST grows too much
|
record // keep this below 32 bytes; otherwise the AST grows too much
|
||||||
typ: PType;
|
typ: PType;
|
||||||
comment: string;
|
comment: string;
|
||||||
info: TLineInfo;
|
info: TLineInfo;
|
||||||
base: TNumericalBase; // only valid for int or float literals
|
flags: TNodeFlags;
|
||||||
case Kind: TNodeKind of
|
case Kind: TNodeKind of
|
||||||
nkCharLit..nkInt64Lit:
|
nkCharLit..nkInt64Lit:
|
||||||
(intVal: biggestInt);
|
(intVal: biggestInt);
|
||||||
|
|
@ -279,6 +296,7 @@ type
|
||||||
(strVal: string);
|
(strVal: string);
|
||||||
nkSym: (sym: PSym);
|
nkSym: (sym: PSym);
|
||||||
nkIdent: (ident: PIdent);
|
nkIdent: (ident: PIdent);
|
||||||
|
nkMetaNode: (nodePtr: PNodePtr);
|
||||||
else (sons: TNodeSeq);
|
else (sons: TNodeSeq);
|
||||||
end; }
|
end; }
|
||||||
|
|
||||||
|
|
@ -307,27 +325,27 @@ type
|
||||||
);
|
);
|
||||||
|
|
||||||
TLocFlag = (
|
TLocFlag = (
|
||||||
// lfIndirect, // location needs to be derefered
|
lfIndirect, // backend introduced a pointer
|
||||||
lfOnStack, // location is on hardware stack
|
|
||||||
lfOnHeap, // location is on heap
|
|
||||||
lfOnData, // location is in the static constant data
|
|
||||||
lfOnUnknown, // location is unknown (stack, heap or static)
|
|
||||||
// other backend-flags:
|
|
||||||
lfNoDeepCopy, // no need for a deep copy
|
lfNoDeepCopy, // no need for a deep copy
|
||||||
lfNoDecl, // do not declare it in C
|
lfNoDecl, // do not declare it in C
|
||||||
lfDynamicLib, // link symbol to dynamic library
|
lfDynamicLib, // link symbol to dynamic library
|
||||||
lfHeader // include header file for symbol
|
lfHeader // include header file for symbol
|
||||||
);
|
);
|
||||||
|
|
||||||
|
TStorageLoc = (
|
||||||
|
OnUnknown, // location is unknown (stack, heap or static)
|
||||||
|
OnStack, // location is on hardware stack
|
||||||
|
OnHeap // location is on heap or global (reference counting needed)
|
||||||
|
);
|
||||||
|
|
||||||
TLocFlags = set of TLocFlag;
|
TLocFlags = set of TLocFlag;
|
||||||
TLoc = record
|
TLoc = record
|
||||||
k: TLocKind; // kind of location
|
k: TLocKind; // kind of location
|
||||||
t: PType; // type of location
|
s: TStorageLoc;
|
||||||
r: PRope; // rope value of location (C code generator)
|
|
||||||
a: int; // location's "address", i.e. slot for temporaries
|
|
||||||
flags: TLocFlags; // location's flags
|
flags: TLocFlags; // location's flags
|
||||||
indirect: int; // count the number of dereferences needed to access the
|
t: PType; // type of location
|
||||||
// location
|
r: PRope; // rope value of location (code generators)
|
||||||
|
a: int; // location's "address", i.e. slot for temporaries
|
||||||
end;
|
end;
|
||||||
|
|
||||||
// ---------------- end of backend information ------------------------------
|
// ---------------- end of backend information ------------------------------
|
||||||
|
|
@ -447,7 +465,7 @@ type
|
||||||
PLib = ^TLib;
|
PLib = ^TLib;
|
||||||
|
|
||||||
const
|
const
|
||||||
OverloadableSyms = {@set}[skProc, skIterator, skEnumField];
|
OverloadableSyms = {@set}[skProc, skIterator, skConverter];
|
||||||
|
|
||||||
const // "MagicToStr" array:
|
const // "MagicToStr" array:
|
||||||
MagicToStr: array [TMagic] of string = (
|
MagicToStr: array [TMagic] of string = (
|
||||||
|
|
@ -474,15 +492,22 @@ const // "MagicToStr" array:
|
||||||
'EqProc', 'EqUntracedRef', 'LePtr', 'LtPtr', 'EqCString', 'Xor',
|
'EqProc', 'EqUntracedRef', 'LePtr', 'LtPtr', 'EqCString', 'Xor',
|
||||||
'UnaryMinusI', 'UnaryMinusI64', 'AbsI', 'AbsI64', 'Not', 'UnaryPlusI',
|
'UnaryMinusI', 'UnaryMinusI64', 'AbsI', 'AbsI64', 'Not', 'UnaryPlusI',
|
||||||
'BitnotI', 'UnaryPlusI64', 'BitnotI64', 'UnaryPlusF64', 'UnaryMinusF64', 'AbsF64',
|
'BitnotI', 'UnaryPlusI64', 'BitnotI64', 'UnaryPlusF64', 'UnaryMinusF64', 'AbsF64',
|
||||||
'Ze', 'Ze64', 'ToU8', 'ToU16', 'ToU32', 'ToFloat',
|
'Ze8ToI', 'Ze8ToI64', 'Ze16ToI', 'Ze16ToI64', 'Ze32ToI64', 'ZeIToI64',
|
||||||
'ToBiggestFloat', 'ToInt', 'ToBiggestInt', 'And', 'Or', 'EqStr',
|
'ToU8', 'ToU16', 'ToU32', 'ToFloat', 'ToBiggestFloat', 'ToInt',
|
||||||
'LeStr', 'LtStr', 'EqSet', 'LeSet', 'LtSet', 'MulSet',
|
'ToBiggestInt', 'CharToStr', 'BoolToStr', 'IntToStr', 'Int64ToStr', 'FloatToStr',
|
||||||
'PlusSet', 'MinusSet', 'SymDiffSet', 'ConStrStr', 'ConArrArr', 'ConArrT',
|
'CStrToStr', 'StrToStr', 'And', 'Or', 'EqStr', 'LeStr',
|
||||||
'ConTArr', 'ConTT', 'Slice', 'AppendStrCh', 'AppendStrStr', 'AppendSeqElem',
|
'LtStr', 'EqSet', 'LeSet', 'LtSet', 'MulSet', 'PlusSet',
|
||||||
'AppendSeqSeq', 'InRange', 'InSet', 'Is', 'Asgn', 'Repr',
|
'MinusSet', 'SymDiffSet', 'ConStrStr', 'ConArrArr', 'ConArrT', 'ConTArr',
|
||||||
'Exit', 'SetLengthStr', 'SetLengthSeq', 'Assert', 'Swap', 'Array',
|
'ConTT', 'Slice', 'AppendStrCh', 'AppendStrStr', 'AppendSeqElem', 'AppendSeqSeq',
|
||||||
'OpenArray', 'Range', 'Tuple', 'Set', 'Seq', 'CompileDate',
|
'InRange', 'InSet', 'Is', 'Asgn', 'Repr', 'Exit',
|
||||||
'CompileTime', 'NimrodVersion', 'NimrodMajor', 'NimrodMinor', 'NimrodPatch', 'CpuEndian'
|
'SetLengthStr', 'SetLengthSeq', 'Assert', 'Swap', 'IsNil', 'Array',
|
||||||
|
'OpenArray', 'Range', 'Set', 'Seq', 'CompileDate', 'CompileTime',
|
||||||
|
'NimrodVersion', 'NimrodMajor', 'NimrodMinor', 'NimrodPatch', 'CpuEndian', 'NaN',
|
||||||
|
'Inf', 'NegInf', 'NLen', 'NChild', 'NSetChild', 'NAdd',
|
||||||
|
'NAddMultiple', 'NDel', 'NKind', 'NIntVal', 'NFloatVal', 'NSymbol',
|
||||||
|
'NIdent', 'NGetType', 'NStrVal', 'NSetIntVal', 'NSetFloatVal', 'NSetSymbol',
|
||||||
|
'NSetIdent', 'NSetType', 'NSetStrVal', 'NNewNimNode', 'NCopyNimNode', 'NCopyNimTree',
|
||||||
|
'StrToIdent', 'IdentToStr', 'EqIdent', 'NHint', 'NWarning', 'NError'
|
||||||
//[[[end]]]
|
//[[[end]]]
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
@ -490,7 +515,7 @@ const
|
||||||
GenericTypes: TTypeKinds = {@set}[tyGeneric, tyGenericParam];
|
GenericTypes: TTypeKinds = {@set}[tyGeneric, tyGenericParam];
|
||||||
|
|
||||||
StructuralEquivTypes: TTypeKinds = {@set}[
|
StructuralEquivTypes: TTypeKinds = {@set}[
|
||||||
tyEmptySet, tyArrayConstr, tyNil, tyRecordConstr, tyTuple,
|
tyEmptySet, tyArrayConstr, tyNil, tyTuple,
|
||||||
tyArray,
|
tyArray,
|
||||||
tySet,
|
tySet,
|
||||||
tyRange,
|
tyRange,
|
||||||
|
|
@ -503,16 +528,16 @@ const
|
||||||
ConcreteTypes: TTypeKinds = {@set}[
|
ConcreteTypes: TTypeKinds = {@set}[
|
||||||
// types of the expr that may occur in::
|
// types of the expr that may occur in::
|
||||||
// var x = expr
|
// var x = expr
|
||||||
tyBool, tyChar, tyEnum, tyArray, tyRecord, tyObject, tySet, tyTuple,
|
tyBool, tyChar, tyEnum, tyArray, tyObject, tySet, tyTuple,
|
||||||
tyRange, tyPtr, tyRef, tyVar, tySequence, tyProc,
|
tyRange, tyPtr, tyRef, tyVar, tySequence, tyProc,
|
||||||
tyPointer, tyOpenArray,
|
tyPointer, tyOpenArray,
|
||||||
tyString, tyCString,
|
tyString, tyCString,
|
||||||
tyInt..tyInt64,
|
tyInt..tyInt64,
|
||||||
tyFloat..tyFloat128
|
tyFloat..tyFloat128
|
||||||
];
|
];
|
||||||
ConstantDataTypes: TTypeKinds = {@set}[tyArray, tyRecord, tySet, tyTuple];
|
ConstantDataTypes: TTypeKinds = {@set}[tyArray, tySet, tyTuple];
|
||||||
ExportableSymKinds = {@set}[skVar, skConst, skProc, skType, skEnumField,
|
ExportableSymKinds = {@set}[skVar, skConst, skProc, skType,
|
||||||
skIterator, skMacro, skTemplate];
|
skIterator, skMacro, skTemplate, skConverter];
|
||||||
namePos = 0;
|
namePos = 0;
|
||||||
genericParamsPos = 1;
|
genericParamsPos = 1;
|
||||||
paramsPos = 2;
|
paramsPos = 2;
|
||||||
|
|
@ -534,7 +559,7 @@ function newIntTypeNode(kind: TNodeKind; const intVal: BiggestInt;
|
||||||
typ: PType): PNode;
|
typ: PType): PNode;
|
||||||
function newFloatNode(kind: TNodeKind; const floatVal: BiggestFloat): PNode;
|
function newFloatNode(kind: TNodeKind; const floatVal: BiggestFloat): PNode;
|
||||||
function newStrNode(kind: TNodeKind; const strVal: string): PNode;
|
function newStrNode(kind: TNodeKind; const strVal: string): PNode;
|
||||||
function newIdentNode(ident: PIdent): PNode;
|
function newIdentNode(ident: PIdent; const info: TLineInfo): PNode;
|
||||||
function newSymNode(sym: PSym): PNode;
|
function newSymNode(sym: PSym): PNode;
|
||||||
function newNodeI(kind: TNodeKind; const info: TLineInfo): PNode;
|
function newNodeI(kind: TNodeKind; const info: TLineInfo): PNode;
|
||||||
function newNodeIT(kind: TNodeKind; const info: TLineInfo; typ: PType): PNode;
|
function newNodeIT(kind: TNodeKind; const info: TLineInfo; typ: PType): PNode;
|
||||||
|
|
@ -548,7 +573,7 @@ procedure initNodeTable(out x: TNodeTable);
|
||||||
|
|
||||||
// copy procs:
|
// copy procs:
|
||||||
function copyType(t: PType; owner: PSym): PType;
|
function copyType(t: PType; owner: PSym): PType;
|
||||||
function copySym(s: PSym; owner: PSym): PSym;
|
function copySym(s: PSym; keepId: bool = false): PSym;
|
||||||
procedure assignType(dest, src: PType);
|
procedure assignType(dest, src: PType);
|
||||||
|
|
||||||
procedure copyStrTable(out dest: TStrTable; const src: TStrTable);
|
procedure copyStrTable(out dest: TStrTable; const src: TStrTable);
|
||||||
|
|
@ -620,7 +645,7 @@ begin
|
||||||
if b.kind in [nkStrLit..nkTripleStrLit] then
|
if b.kind in [nkStrLit..nkTripleStrLit] then
|
||||||
result := a.strVal <= b.strVal;
|
result := a.strVal <= b.strVal;
|
||||||
end
|
end
|
||||||
else assert(false);
|
else InternalError(a.info, 'leValue');
|
||||||
end
|
end
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
@ -638,7 +663,7 @@ begin
|
||||||
if b.kind in [nkStrLit..nkTripleStrLit] then
|
if b.kind in [nkStrLit..nkTripleStrLit] then
|
||||||
result := a.strVal = b.strVal;
|
result := a.strVal = b.strVal;
|
||||||
end
|
end
|
||||||
else assert(false);
|
else InternalError(a.info, 'SameValue');
|
||||||
end
|
end
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
@ -652,7 +677,7 @@ begin
|
||||||
nkStrLit..nkTripleStrLit:
|
nkStrLit..nkTripleStrLit:
|
||||||
result := a.strVal;
|
result := a.strVal;
|
||||||
else begin
|
else begin
|
||||||
assert(false);
|
InternalError(a.info, 'valueToString');
|
||||||
result := ''
|
result := ''
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
@ -663,6 +688,9 @@ var
|
||||||
i: int;
|
i: int;
|
||||||
begin
|
begin
|
||||||
dest.counter := src.counter;
|
dest.counter := src.counter;
|
||||||
|
{@emit
|
||||||
|
if isNil(src.data) then exit;
|
||||||
|
}
|
||||||
setLength(dest.data, length(src.data));
|
setLength(dest.data, length(src.data));
|
||||||
for i := 0 to high(src.data) do
|
for i := 0 to high(src.data) do
|
||||||
dest.data[i] := src.data[i];
|
dest.data[i] := src.data[i];
|
||||||
|
|
@ -673,6 +701,9 @@ var
|
||||||
i: int;
|
i: int;
|
||||||
begin
|
begin
|
||||||
dest.counter := src.counter;
|
dest.counter := src.counter;
|
||||||
|
{@emit
|
||||||
|
if isNil(src.data) then exit;
|
||||||
|
}
|
||||||
setLength(dest.data, length(src.data));
|
setLength(dest.data, length(src.data));
|
||||||
for i := 0 to high(src.data) do
|
for i := 0 to high(src.data) do
|
||||||
dest.data[i] := src.data[i];
|
dest.data[i] := src.data[i];
|
||||||
|
|
@ -683,6 +714,9 @@ var
|
||||||
i: int;
|
i: int;
|
||||||
begin
|
begin
|
||||||
dest.counter := src.counter;
|
dest.counter := src.counter;
|
||||||
|
{@emit
|
||||||
|
if isNil(src.data) then exit;
|
||||||
|
}
|
||||||
setLength(dest.data, length(src.data));
|
setLength(dest.data, length(src.data));
|
||||||
for i := 0 to high(src.data) do
|
for i := 0 to high(src.data) do
|
||||||
dest.data[i] := src.data[i];
|
dest.data[i] := src.data[i];
|
||||||
|
|
@ -700,7 +734,7 @@ begin
|
||||||
FillChar(result^, sizeof(result^), 0);
|
FillChar(result^, sizeof(result^), 0);
|
||||||
{@emit}
|
{@emit}
|
||||||
result.kind := kind;
|
result.kind := kind;
|
||||||
result.info := UnknownLineInfo;
|
result.info := UnknownLineInfo();
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function newIntNode(kind: TNodeKind; const intVal: BiggestInt): PNode;
|
function newIntNode(kind: TNodeKind; const intVal: BiggestInt): PNode;
|
||||||
|
|
@ -728,10 +762,11 @@ begin
|
||||||
result.strVal := strVal
|
result.strVal := strVal
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function newIdentNode(ident: PIdent): PNode;
|
function newIdentNode(ident: PIdent; const info: TLineInfo): PNode;
|
||||||
begin
|
begin
|
||||||
result := newNode(nkIdent);
|
result := newNode(nkIdent);
|
||||||
result.ident := ident
|
result.ident := ident;
|
||||||
|
result.info := info;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function newSymNode(sym: PSym): PNode;
|
function newSymNode(sym: PSym): PNode;
|
||||||
|
|
@ -778,6 +813,7 @@ begin
|
||||||
dest.n := src.n;
|
dest.n := src.n;
|
||||||
dest.size := src.size;
|
dest.size := src.size;
|
||||||
dest.align := src.align;
|
dest.align := src.align;
|
||||||
|
dest.containerID := src.containerID;
|
||||||
newSons(dest, sonsLen(src));
|
newSons(dest, sonsLen(src));
|
||||||
for i := 0 to sonsLen(src)-1 do
|
for i := 0 to sonsLen(src)-1 do
|
||||||
dest.sons[i] := src.sons[i];
|
dest.sons[i] := src.sons[i];
|
||||||
|
|
@ -793,14 +829,13 @@ begin
|
||||||
// backend-info should not be copied
|
// backend-info should not be copied
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function copySym(s: PSym; owner: PSym): PSym;
|
function copySym(s: PSym; keepId: bool = false): PSym;
|
||||||
begin
|
begin
|
||||||
result := newSym(s.kind, s.name, owner);
|
result := newSym(s.kind, s.name, s.owner);
|
||||||
result.ast := nil; // BUGFIX; was: s.ast which made problems
|
result.ast := nil; // BUGFIX; was: s.ast which made problems
|
||||||
result.info := s.info;
|
result.info := s.info;
|
||||||
result.typ := s.typ;
|
result.typ := s.typ;
|
||||||
if owner = s.owner then result.id := s.id
|
if keepId then result.id := s.id else result.id := getID();
|
||||||
else result.id := getID();
|
|
||||||
result.flags := s.flags;
|
result.flags := s.flags;
|
||||||
result.magic := s.magic;
|
result.magic := s.magic;
|
||||||
copyStrTable(result.tab, s.tab);
|
copyStrTable(result.tab, s.tab);
|
||||||
|
|
@ -820,7 +855,7 @@ begin
|
||||||
result.Name := Name;
|
result.Name := Name;
|
||||||
result.Kind := symKind;
|
result.Kind := symKind;
|
||||||
result.flags := {@set}[];
|
result.flags := {@set}[];
|
||||||
result.info := UnknownLineInfo;
|
result.info := UnknownLineInfo();
|
||||||
result.options := gOptions;
|
result.options := gOptions;
|
||||||
result.owner := owner;
|
result.owner := owner;
|
||||||
result.offset := -1;
|
result.offset := -1;
|
||||||
|
|
@ -972,7 +1007,7 @@ begin
|
||||||
result := newNode(src.kind);
|
result := newNode(src.kind);
|
||||||
result.info := src.info;
|
result.info := src.info;
|
||||||
result.typ := src.typ;
|
result.typ := src.typ;
|
||||||
result.base := src.base;
|
result.flags := src.flags;
|
||||||
case src.Kind of
|
case src.Kind of
|
||||||
nkCharLit..nkInt64Lit:
|
nkCharLit..nkInt64Lit:
|
||||||
result.intVal := src.intVal;
|
result.intVal := src.intVal;
|
||||||
|
|
@ -984,6 +1019,8 @@ begin
|
||||||
result.ident := src.ident;
|
result.ident := src.ident;
|
||||||
nkStrLit..nkTripleStrLit:
|
nkStrLit..nkTripleStrLit:
|
||||||
result.strVal := src.strVal;
|
result.strVal := src.strVal;
|
||||||
|
nkMetaNode:
|
||||||
|
result.nodePtr := src.nodePtr;
|
||||||
else begin end;
|
else begin end;
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
@ -994,12 +1031,31 @@ var
|
||||||
i: int;
|
i: int;
|
||||||
begin
|
begin
|
||||||
if src = nil then begin result := nil; exit end;
|
if src = nil then begin result := nil; exit end;
|
||||||
result := copyNode(src);
|
result := newNode(src.kind);
|
||||||
result.sons := nil; // BUGFIX
|
result.info := src.info;
|
||||||
|
result.typ := src.typ;
|
||||||
|
result.flags := src.flags;
|
||||||
|
case src.Kind of
|
||||||
|
nkCharLit..nkInt64Lit:
|
||||||
|
result.intVal := src.intVal;
|
||||||
|
nkFloatLit, nkFloat32Lit, nkFloat64Lit:
|
||||||
|
result.floatVal := src.floatVal;
|
||||||
|
nkSym:
|
||||||
|
result.sym := src.sym;
|
||||||
|
nkIdent:
|
||||||
|
result.ident := src.ident;
|
||||||
|
nkStrLit..nkTripleStrLit:
|
||||||
|
result.strVal := src.strVal;
|
||||||
|
nkMetaNode:
|
||||||
|
result.nodePtr := src.nodePtr;
|
||||||
|
else begin
|
||||||
|
result.sons := nil;
|
||||||
newSons(result, sonsLen(src));
|
newSons(result, sonsLen(src));
|
||||||
for i := 0 to sonsLen(src)-1 do
|
for i := 0 to sonsLen(src)-1 do
|
||||||
result.sons[i] := copyTree(src.sons[i]);
|
result.sons[i] := copyTree(src.sons[i]);
|
||||||
end;
|
end;
|
||||||
|
end
|
||||||
|
end;
|
||||||
|
|
||||||
function lastSon(n: PNode): PNode;
|
function lastSon(n: PNode): PNode;
|
||||||
begin
|
begin
|
||||||
|
|
|
||||||
146
nim/astalgo.pas
146
nim/astalgo.pas
|
|
@ -136,6 +136,10 @@ procedure debug(n: PNode); overload;
|
||||||
function IdTableGet(const t: TIdTable; key: PIdObj): PObject;
|
function IdTableGet(const t: TIdTable; key: PIdObj): PObject;
|
||||||
procedure IdTablePut(var t: TIdTable; key: PIdObj; val: PObject);
|
procedure IdTablePut(var t: TIdTable; key: PIdObj; val: PObject);
|
||||||
|
|
||||||
|
function IdTableHasObjectAsKey(const t: TIdTable; key: PIdObj): bool;
|
||||||
|
// checks if `t` contains the `key` (compared by the pointer value, not only
|
||||||
|
// `key`'s id)
|
||||||
|
|
||||||
function IdNodeTableGet(const t: TIdNodeTable; key: PIdObj): PNode;
|
function IdNodeTableGet(const t: TIdNodeTable; key: PIdObj): PNode;
|
||||||
procedure IdNodeTablePut(var t: TIdNodeTable; key: PIdObj; val: PNode);
|
procedure IdNodeTablePut(var t: TIdNodeTable; key: PIdObj; val: PNode);
|
||||||
|
|
||||||
|
|
@ -180,8 +184,6 @@ function nextTry(h, maxHash: THash): THash;
|
||||||
implementation
|
implementation
|
||||||
|
|
||||||
function lookupInRecord(n: PNode; field: PIdent): PSym;
|
function lookupInRecord(n: PNode; field: PIdent): PSym;
|
||||||
// XXX: transform in a node that contains the runtime check for the
|
|
||||||
// field, if it is in a case-part...
|
|
||||||
var
|
var
|
||||||
i: int;
|
i: int;
|
||||||
begin
|
begin
|
||||||
|
|
@ -194,7 +196,7 @@ begin
|
||||||
end
|
end
|
||||||
end;
|
end;
|
||||||
nkRecCase: begin
|
nkRecCase: begin
|
||||||
assert(n.sons[0].kind = nkSym);
|
if (n.sons[0].kind <> nkSym) then InternalError(n.info, 'lookupInRecord');
|
||||||
result := lookupInRecord(n.sons[0], field);
|
result := lookupInRecord(n.sons[0], field);
|
||||||
if result <> nil then exit;
|
if result <> nil then exit;
|
||||||
for i := 1 to sonsLen(n)-1 do begin
|
for i := 1 to sonsLen(n)-1 do begin
|
||||||
|
|
@ -203,7 +205,7 @@ begin
|
||||||
result := lookupInRecord(lastSon(n.sons[i]), field);
|
result := lookupInRecord(lastSon(n.sons[i]), field);
|
||||||
if result <> nil then exit;
|
if result <> nil then exit;
|
||||||
end;
|
end;
|
||||||
else internalError('lookupInRecord(record case branch)');
|
else internalError(n.info, 'lookupInRecord(record case branch)');
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end;
|
end;
|
||||||
|
|
@ -226,7 +228,8 @@ var
|
||||||
i: int;
|
i: int;
|
||||||
begin
|
begin
|
||||||
for i := start to sonsLen(list)-1 do begin
|
for i := start to sonsLen(list)-1 do begin
|
||||||
assert(list.sons[i].kind = nkSym);
|
if list.sons[i].kind <> nkSym then
|
||||||
|
InternalError(list.info, 'getSymFromList');
|
||||||
result := list.sons[i].sym;
|
result := list.sons[i].sym;
|
||||||
if result.name.id = ident.id then exit
|
if result.name.id = ident.id then exit
|
||||||
end;
|
end;
|
||||||
|
|
@ -342,7 +345,7 @@ end;
|
||||||
|
|
||||||
function lineInfoToStr(const info: TLineInfo): PRope;
|
function lineInfoToStr(const info: TLineInfo): PRope;
|
||||||
begin
|
begin
|
||||||
result := ropeFormat('[$1, $2, $3]', [makeYamlString(toFilename(info)),
|
result := ropef('[$1, $2, $3]', [makeYamlString(toFilename(info)),
|
||||||
toRope(toLinenumber(info)), toRope(toColumn(info))]);
|
toRope(toLinenumber(info)), toRope(toColumn(info))]);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
@ -367,11 +370,11 @@ begin
|
||||||
for i := 0 to high(n.data) do
|
for i := 0 to high(n.data) do
|
||||||
if n.data[i] <> nil then begin
|
if n.data[i] <> nil then begin
|
||||||
if mycount > 0 then app(result, ','+'');
|
if mycount > 0 then app(result, ','+'');
|
||||||
appRopeFormat(result, '$n$1$2',
|
appf(result, '$n$1$2',
|
||||||
[istr, symToYamlAux(n.data[i], marker, indent+2, maxRecDepth-1)]);
|
[istr, symToYamlAux(n.data[i], marker, indent+2, maxRecDepth-1)]);
|
||||||
inc(mycount)
|
inc(mycount)
|
||||||
end;
|
end;
|
||||||
if mycount > 0 then appRopeFormat(result, '$n$1', [spaces(indent)]);
|
if mycount > 0 then appf(result, '$n$1', [spaces(indent)]);
|
||||||
app(result, ']'+'');
|
app(result, ']'+'');
|
||||||
assert(mycount = n.counter);
|
assert(mycount = n.counter);
|
||||||
end;
|
end;
|
||||||
|
|
@ -387,10 +390,10 @@ begin
|
||||||
i := 0;
|
i := 0;
|
||||||
while i <= high(c) do begin
|
while i <= high(c) do begin
|
||||||
if i > 0 then app(result, ','+'');
|
if i > 0 then app(result, ','+'');
|
||||||
appRopeFormat(result, '$n$1"$2": $3', [istr, c[i], c[i+1]]);
|
appf(result, '$n$1"$2": $3', [istr, c[i], c[i+1]]);
|
||||||
inc(i, 2)
|
inc(i, 2)
|
||||||
end;
|
end;
|
||||||
appRopeFormat(result, '$n$1}', [spaces(indent)]);
|
appf(result, '$n$1}', [spaces(indent)]);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function symToYamlAux(n: PSym; var marker: TObjectSet;
|
function symToYamlAux(n: PSym; var marker: TObjectSet;
|
||||||
|
|
@ -401,7 +404,7 @@ begin
|
||||||
if n = nil then
|
if n = nil then
|
||||||
result := toRope('null')
|
result := toRope('null')
|
||||||
else if ObjectSetContainsOrIncl(marker, n) then
|
else if ObjectSetContainsOrIncl(marker, n) then
|
||||||
result := ropeFormat('"$1 @$2"', [
|
result := ropef('"$1 @$2"', [
|
||||||
toRope(n.name.s),
|
toRope(n.name.s),
|
||||||
toRope(strutils.toHex({@cast}TAddress(n), sizeof(n)*2))])
|
toRope(strutils.toHex({@cast}TAddress(n), sizeof(n)*2))])
|
||||||
else begin
|
else begin
|
||||||
|
|
@ -427,7 +430,7 @@ begin
|
||||||
if n = nil then
|
if n = nil then
|
||||||
result := toRope('null')
|
result := toRope('null')
|
||||||
else if objectSetContainsOrIncl(marker, n) then
|
else if objectSetContainsOrIncl(marker, n) then
|
||||||
result := ropeFormat('"$1 @$2"', [
|
result := ropef('"$1 @$2"', [
|
||||||
toRope(typeKindToStr[n.kind]),
|
toRope(typeKindToStr[n.kind]),
|
||||||
toRope(strutils.toHex({@cast}TAddress(n), sizeof(n)*2))])
|
toRope(strutils.toHex({@cast}TAddress(n), sizeof(n)*2))])
|
||||||
else begin
|
else begin
|
||||||
|
|
@ -453,48 +456,48 @@ begin
|
||||||
result := toRope('null')
|
result := toRope('null')
|
||||||
else begin
|
else begin
|
||||||
istr := spaces(indent+2);
|
istr := spaces(indent+2);
|
||||||
result := ropeFormat('{$n$1"kind": $2',
|
result := ropef('{$n$1"kind": $2',
|
||||||
[istr, makeYamlString(nodeKindToStr[n.kind])]);
|
[istr, makeYamlString(nodeKindToStr[n.kind])]);
|
||||||
if maxRecDepth <> 0 then begin
|
if maxRecDepth <> 0 then begin
|
||||||
appRopeFormat(result, ',$n$1"typ": $2',
|
appf(result, ',$n$1"info": $2',
|
||||||
[istr, typeToYamlAux(n.typ, marker, indent+2, maxRecDepth)]);
|
|
||||||
appRopeFormat(result, ',$n$1"info": $2',
|
|
||||||
[istr, lineInfoToStr(n.info)]);
|
[istr, lineInfoToStr(n.info)]);
|
||||||
case n.kind of
|
case n.kind of
|
||||||
nkCharLit..nkInt64Lit:
|
nkCharLit..nkInt64Lit:
|
||||||
appRopeFormat(result, '$n$1"intVal": $2', [istr, toRope(n.intVal)]);
|
appf(result, '$n$1"intVal": $2', [istr, toRope(n.intVal)]);
|
||||||
nkFloatLit, nkFloat32Lit, nkFloat64Lit:
|
nkFloatLit, nkFloat32Lit, nkFloat64Lit:
|
||||||
appRopeFormat(result, '$n$1"floatVal": $2',
|
appf(result, '$n$1"floatVal": $2',
|
||||||
[istr, toRopeF(n.floatVal)]);
|
[istr, toRopeF(n.floatVal)]);
|
||||||
nkStrLit..nkTripleStrLit:
|
nkStrLit..nkTripleStrLit:
|
||||||
appRopeFormat(result, '$n$1"strVal": $2',
|
appf(result, '$n$1"strVal": $2',
|
||||||
[istr, makeYamlString(n.strVal)]);
|
[istr, makeYamlString(n.strVal)]);
|
||||||
nkSym:
|
nkSym:
|
||||||
appRopeFormat(result, ',$n$1"sym": $2',
|
appf(result, ',$n$1"sym": $2',
|
||||||
[istr, symToYamlAux(n.sym, marker, indent+2, maxRecDepth)]);
|
[istr, symToYamlAux(n.sym, marker, indent+2, maxRecDepth)]);
|
||||||
|
|
||||||
nkIdent: begin
|
nkIdent: begin
|
||||||
if n.ident <> nil then
|
if n.ident <> nil then
|
||||||
appRopeFormat(result, '$n$1"ident": $2',
|
appf(result, '$n$1"ident": $2',
|
||||||
[istr, makeYamlString(n.ident.s)])
|
[istr, makeYamlString(n.ident.s)])
|
||||||
else
|
else
|
||||||
appRopeFormat(result, '$n$1"ident": null', [istr])
|
appf(result, '$n$1"ident": null', [istr])
|
||||||
end
|
end
|
||||||
else begin
|
else begin
|
||||||
if sonsLen(n) > 0 then begin
|
if sonsLen(n) > 0 then begin
|
||||||
appRopeFormat(result, ',$n$1"sons": [', [istr]);
|
appf(result, ',$n$1"sons": [', [istr]);
|
||||||
for i := 0 to sonsLen(n)-1 do begin
|
for i := 0 to sonsLen(n)-1 do begin
|
||||||
if i > 0 then app(result, ','+'');
|
if i > 0 then app(result, ','+'');
|
||||||
appRopeFormat(result, '$n$1$2',
|
appf(result, '$n$1$2',
|
||||||
[spaces(indent+4),
|
[spaces(indent+4),
|
||||||
treeToYamlAux(n.sons[i], marker, indent + 4, maxRecDepth-1)]);
|
treeToYamlAux(n.sons[i], marker, indent + 4, maxRecDepth-1)]);
|
||||||
end;
|
end;
|
||||||
appRopeFormat(result, '$n$1]', [istr]);
|
appf(result, '$n$1]', [istr]);
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end;
|
end;
|
||||||
appRopeFormat(result, '$n$1}', [spaces(indent)]);
|
appf(result, ',$n$1"typ": $2',
|
||||||
|
[istr, typeToYamlAux(n.typ, marker, indent+2, maxRecDepth)]);
|
||||||
|
end;
|
||||||
|
appf(result, '$n$1}', [spaces(indent)]);
|
||||||
end
|
end
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
@ -523,19 +526,88 @@ begin
|
||||||
end;
|
end;
|
||||||
|
|
||||||
// these are for debugging only:
|
// these are for debugging only:
|
||||||
|
function debugType(n: PType): PRope;
|
||||||
|
var
|
||||||
|
i: int;
|
||||||
|
begin
|
||||||
|
if n = nil then
|
||||||
|
result := toRope('null')
|
||||||
|
else begin
|
||||||
|
result := toRope(typeKindToStr[n.kind]);
|
||||||
|
app(result, '('+'');
|
||||||
|
for i := 0 to sonsLen(n)-1 do begin
|
||||||
|
if i > 0 then app(result, ', ');
|
||||||
|
if n.sons[i] = nil then app(result, 'null')
|
||||||
|
else app(result, debugType(n.sons[i]));
|
||||||
|
// app(result, typeKindToStr[n.sons[i].kind]);
|
||||||
|
end;
|
||||||
|
app(result, ')'+'');
|
||||||
|
end
|
||||||
|
end;
|
||||||
|
|
||||||
|
function debugTree(n: PNode; indent: int; maxRecDepth: int): PRope;
|
||||||
|
var
|
||||||
|
istr: PRope;
|
||||||
|
i: int;
|
||||||
|
begin
|
||||||
|
if n = nil then
|
||||||
|
result := toRope('null')
|
||||||
|
else begin
|
||||||
|
istr := spaces(indent+2);
|
||||||
|
result := ropef('{$n$1"kind": $2',
|
||||||
|
[istr, makeYamlString(nodeKindToStr[n.kind])]);
|
||||||
|
if maxRecDepth <> 0 then begin
|
||||||
|
case n.kind of
|
||||||
|
nkCharLit..nkInt64Lit:
|
||||||
|
appf(result, '$n$1"intVal": $2', [istr, toRope(n.intVal)]);
|
||||||
|
nkFloatLit, nkFloat32Lit, nkFloat64Lit:
|
||||||
|
appf(result, '$n$1"floatVal": $2',
|
||||||
|
[istr, toRopeF(n.floatVal)]);
|
||||||
|
nkStrLit..nkTripleStrLit:
|
||||||
|
appf(result, '$n$1"strVal": $2',
|
||||||
|
[istr, makeYamlString(n.strVal)]);
|
||||||
|
nkSym:
|
||||||
|
appf(result, ',$n$1"sym": $2_$3',
|
||||||
|
[istr, toRope(n.sym.name.s), toRope(n.sym.id)]);
|
||||||
|
|
||||||
|
nkIdent: begin
|
||||||
|
if n.ident <> nil then
|
||||||
|
appf(result, '$n$1"ident": $2',
|
||||||
|
[istr, makeYamlString(n.ident.s)])
|
||||||
|
else
|
||||||
|
appf(result, '$n$1"ident": null', [istr])
|
||||||
|
end
|
||||||
|
else begin
|
||||||
|
if sonsLen(n) > 0 then begin
|
||||||
|
appf(result, ',$n$1"sons": [', [istr]);
|
||||||
|
for i := 0 to sonsLen(n)-1 do begin
|
||||||
|
if i > 0 then app(result, ','+'');
|
||||||
|
appf(result, '$n$1$2',
|
||||||
|
[spaces(indent+4),
|
||||||
|
debugTree(n.sons[i], indent + 4, maxRecDepth-1)]);
|
||||||
|
end;
|
||||||
|
appf(result, '$n$1]', [istr]);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
appf(result, '$n$1}', [spaces(indent)]);
|
||||||
|
end
|
||||||
|
end;
|
||||||
|
|
||||||
procedure debug(n: PSym); overload;
|
procedure debug(n: PSym); overload;
|
||||||
begin
|
begin
|
||||||
writeln(output, ropeToStr(symToYaml(n, 0, 3)));
|
writeln(output, ropeToStr(ropef('$1_$2', [toRope(n.name.s), toRope(n.id)])));
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure debug(n: PType); overload;
|
procedure debug(n: PType); overload;
|
||||||
begin
|
begin
|
||||||
writeln(output, ropeToStr(typeToYaml(n, 0, 3)));
|
writeln(output, ropeToStr(debugType(n)));
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure debug(n: PNode); overload;
|
procedure debug(n: PNode); overload;
|
||||||
begin
|
begin
|
||||||
writeln(output, ropeToStr(treeToYaml(n, 0, -1)));
|
writeln(output, ropeToStr(debugTree(n, 0, 100)));
|
||||||
end;
|
end;
|
||||||
|
|
||||||
// -------------------- node sets --------------------------------------------
|
// -------------------- node sets --------------------------------------------
|
||||||
|
|
@ -748,7 +820,8 @@ var
|
||||||
begin
|
begin
|
||||||
h := n.name.h and high(data);
|
h := n.name.h and high(data);
|
||||||
while data[h] <> nil do begin
|
while data[h] <> nil do begin
|
||||||
assert(data[h] <> n);
|
if data[h] = n then
|
||||||
|
InternalError(n.info, 'StrTableRawInsert: ' + n.name.s);
|
||||||
h := nextTry(h, high(data))
|
h := nextTry(h, high(data))
|
||||||
end;
|
end;
|
||||||
assert(data[h] = nil);
|
assert(data[h] = nil);
|
||||||
|
|
@ -963,6 +1036,15 @@ begin
|
||||||
result := -1
|
result := -1
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function IdTableHasObjectAsKey(const t: TIdTable; key: PIdObj): bool;
|
||||||
|
var
|
||||||
|
index: int;
|
||||||
|
begin
|
||||||
|
index := IdTableRawGet(t, key);
|
||||||
|
if index >= 0 then result := t.data[index].key = key
|
||||||
|
else result := false
|
||||||
|
end;
|
||||||
|
|
||||||
function IdTableGet(const t: TIdTable; key: PIdObj): PObject;
|
function IdTableGet(const t: TIdTable; key: PIdObj): PObject;
|
||||||
var
|
var
|
||||||
index: int;
|
index: int;
|
||||||
|
|
@ -999,6 +1081,7 @@ begin
|
||||||
end
|
end
|
||||||
else begin
|
else begin
|
||||||
if mustRehash(length(t.data), t.counter) then begin
|
if mustRehash(length(t.data), t.counter) then begin
|
||||||
|
{@emit n := [];}
|
||||||
setLength(n, length(t.data) * growthFactor);
|
setLength(n, length(t.data) * growthFactor);
|
||||||
{@ignore}
|
{@ignore}
|
||||||
fillChar(n[0], length(n)*sizeof(n[0]), 0);
|
fillChar(n[0], length(n)*sizeof(n[0]), 0);
|
||||||
|
|
@ -1083,6 +1166,7 @@ begin
|
||||||
end
|
end
|
||||||
else begin
|
else begin
|
||||||
if mustRehash(length(t.data), t.counter) then begin
|
if mustRehash(length(t.data), t.counter) then begin
|
||||||
|
{@emit n := [];}
|
||||||
setLength(n, length(t.data) * growthFactor);
|
setLength(n, length(t.data) * growthFactor);
|
||||||
{@ignore}
|
{@ignore}
|
||||||
fillChar(n[0], length(n)*sizeof(n[0]), 0);
|
fillChar(n[0], length(n)*sizeof(n[0]), 0);
|
||||||
|
|
|
||||||
|
|
@ -49,17 +49,20 @@ end;
|
||||||
|
|
||||||
procedure BitSetIncl(var x: TBitSet; const elem: BiggestInt);
|
procedure BitSetIncl(var x: TBitSet; const elem: BiggestInt);
|
||||||
begin
|
begin
|
||||||
x[int(elem div ElemSize)] := x[int(elem div ElemSize)] or (1 shl (elem mod ElemSize))
|
assert(elem >= 0);
|
||||||
|
x[int(elem div ElemSize)] := toU8(x[int(elem div ElemSize)] or
|
||||||
|
int(1 shl (elem mod ElemSize)))
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure BitSetExcl(var x: TBitSet; const elem: BiggestInt);
|
procedure BitSetExcl(var x: TBitSet; const elem: BiggestInt);
|
||||||
begin
|
begin
|
||||||
x[int(elem div ElemSize)] := x[int(elem div ElemSize)] and
|
x[int(elem div ElemSize)] := toU8(x[int(elem div ElemSize)] and
|
||||||
not (1 shl (elem mod ElemSize))
|
not int(1 shl (elem mod ElemSize)))
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure BitSetInit(out b: TBitSet; len: int);
|
procedure BitSetInit(out b: TBitSet; len: int);
|
||||||
begin
|
begin
|
||||||
|
{@emit b := [];}
|
||||||
setLength(b, len);
|
setLength(b, len);
|
||||||
{@ignore}
|
{@ignore}
|
||||||
fillChar(b[0], length(b)*sizeof(b[0]), 0);
|
fillChar(b[0], length(b)*sizeof(b[0]), 0);
|
||||||
|
|
@ -70,28 +73,28 @@ procedure BitSetUnion(var x: TBitSet; const y: TBitSet);
|
||||||
var
|
var
|
||||||
i: int;
|
i: int;
|
||||||
begin
|
begin
|
||||||
for i := 0 to high(x) do x[i] := x[i] or int(y[i])
|
for i := 0 to high(x) do x[i] := toU8(x[i] or int(y[i]))
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure BitSetDiff(var x: TBitSet; const y: TBitSet);
|
procedure BitSetDiff(var x: TBitSet; const y: TBitSet);
|
||||||
var
|
var
|
||||||
i: int;
|
i: int;
|
||||||
begin
|
begin
|
||||||
for i := 0 to high(x) do x[i] := x[i] and not int(y[i])
|
for i := 0 to high(x) do x[i] := toU8(x[i] and not int(y[i]))
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure BitSetSymDiff(var x: TBitSet; const y: TBitSet);
|
procedure BitSetSymDiff(var x: TBitSet; const y: TBitSet);
|
||||||
var
|
var
|
||||||
i: int;
|
i: int;
|
||||||
begin
|
begin
|
||||||
for i := 0 to high(x) do x[i] := x[i] xor int(y[i])
|
for i := 0 to high(x) do x[i] := toU8(x[i] xor int(y[i]))
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure BitSetIntersect(var x: TBitSet; const y: TBitSet);
|
procedure BitSetIntersect(var x: TBitSet; const y: TBitSet);
|
||||||
var
|
var
|
||||||
i: int;
|
i: int;
|
||||||
begin
|
begin
|
||||||
for i := 0 to high(x) do x[i] := x[i] and int(y[i])
|
for i := 0 to high(x) do x[i] := toU8(x[i] and int(y[i]))
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function BitSetEquals(const x, y: TBitSet): Boolean;
|
function BitSetEquals(const x, y: TBitSet): Boolean;
|
||||||
|
|
|
||||||
1318
nim/ccgexprs.pas
1318
nim/ccgexprs.pas
File diff suppressed because it is too large
Load diff
205
nim/ccgstmts.pas
205
nim/ccgstmts.pas
|
|
@ -18,17 +18,25 @@ begin
|
||||||
line := toLinenumber(t.info); // BUGFIX
|
line := toLinenumber(t.info); // BUGFIX
|
||||||
if line < 0 then line := 0; // negative numbers are not allowed in #line
|
if line < 0 then line := 0; // negative numbers are not allowed in #line
|
||||||
if optLineDir in p.Options then
|
if optLineDir in p.Options then
|
||||||
appRopeFormat(p.s[cpsStmts], '#line $2 "$1"$n',
|
appf(p.s[cpsStmts], '#line $2 "$1"$n',
|
||||||
[toRope(toFilename(t.info)), toRope(line)]);
|
[toRope(toFilename(t.info)), toRope(line)]);
|
||||||
if ([optStackTrace, optEndb] * p.Options = [optStackTrace, optEndb]) and
|
if ([optStackTrace, optEndb] * p.Options = [optStackTrace, optEndb]) and
|
||||||
((p.prc = nil) or not (sfPure in p.prc.flags)) then begin
|
((p.prc = nil) or not (sfPure in p.prc.flags)) then begin
|
||||||
useMagic('endb'); // new: endb support
|
useMagic(p.module, 'endb'); // new: endb support
|
||||||
appRopeFormat(p.s[cpsStmts], 'endb($1);$n', [toRope(line)])
|
appf(p.s[cpsStmts], 'endb($1);$n', [toRope(line)])
|
||||||
end
|
end
|
||||||
else if ([optLineTrace, optStackTrace] * p.Options =
|
else if ([optLineTrace, optStackTrace] * p.Options =
|
||||||
[optLineTrace, optStackTrace]) and ((p.prc = nil) or
|
[optLineTrace, optStackTrace]) and ((p.prc = nil) or
|
||||||
not (sfPure in p.prc.flags)) then
|
not (sfPure in p.prc.flags)) then
|
||||||
appRopeFormat(p.s[cpsStmts], 'F.line = $1;$n', [toRope(line)])
|
appf(p.s[cpsStmts], 'F.line = $1;$n', [toRope(line)])
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure finishTryStmt(p: BProc; howMany: int);
|
||||||
|
var
|
||||||
|
i: int;
|
||||||
|
begin
|
||||||
|
for i := 1 to howMany do
|
||||||
|
app(p.s[cpsStmts], 'excHandler = excHandler->prev;' + tnl);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure genReturnStmt(p: BProc; t: PNode);
|
procedure genReturnStmt(p: BProc; t: PNode);
|
||||||
|
|
@ -36,15 +44,16 @@ begin
|
||||||
p.beforeRetNeeded := true;
|
p.beforeRetNeeded := true;
|
||||||
genLineDir(p, t);
|
genLineDir(p, t);
|
||||||
if (t.sons[0] <> nil) then genStmts(p, t.sons[0]);
|
if (t.sons[0] <> nil) then genStmts(p, t.sons[0]);
|
||||||
|
finishTryStmt(p, p.nestedTryStmts);
|
||||||
app(p.s[cpsStmts], 'goto BeforeRet;' + tnl)
|
app(p.s[cpsStmts], 'goto BeforeRet;' + tnl)
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure genObjectInit(p: BProc; sym: PSym);
|
procedure genObjectInit(p: BProc; sym: PSym);
|
||||||
begin
|
begin
|
||||||
if containsObject(sym.typ) then begin
|
if containsObject(sym.typ) then begin
|
||||||
useMagic('objectInit');
|
useMagic(p.module, 'objectInit');
|
||||||
appRopeFormat(p.s[cpsInit], 'objectInit($1, $2);$n',
|
appf(p.s[cpsInit], 'objectInit($1, $2);$n',
|
||||||
[addrLoc(sym.loc), genTypeInfo(currMod, sym.typ)])
|
[addrLoc(sym.loc), genTypeInfo(p.module, sym.typ)])
|
||||||
end
|
end
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
@ -52,11 +61,11 @@ procedure initVariable(p: BProc; v: PSym);
|
||||||
begin
|
begin
|
||||||
if containsGarbageCollectedRef(v.typ) or (v.ast = nil) then
|
if containsGarbageCollectedRef(v.typ) or (v.ast = nil) then
|
||||||
// Language change: always initialize variables if v.ast == nil!
|
// Language change: always initialize variables if v.ast == nil!
|
||||||
if not (skipAbstract(v.typ).Kind in [tyArray, tyArrayConstr, tySet,
|
if not (skipVarGenericRange(v.typ).Kind in [tyArray, tyArrayConstr, tySet,
|
||||||
tyRecord, tyTuple, tyObject]) then
|
tyTuple, tyObject]) then
|
||||||
appRopeFormat(p.s[cpsInit], '$1 = 0;$n', [v.loc.r])
|
appf(p.s[cpsStmts], '$1 = 0;$n', [v.loc.r])
|
||||||
else
|
else
|
||||||
appRopeFormat(p.s[cpsInit], 'memset((void*)&$1, 0, sizeof($1));$n',
|
appf(p.s[cpsStmts], 'memset((void*)&$1, 0, sizeof($1));$n',
|
||||||
[v.loc.r])
|
[v.loc.r])
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
@ -73,7 +82,7 @@ begin
|
||||||
assert(a.sons[0].kind = nkSym);
|
assert(a.sons[0].kind = nkSym);
|
||||||
v := a.sons[0].sym;
|
v := a.sons[0].sym;
|
||||||
if sfGlobal in v.flags then
|
if sfGlobal in v.flags then
|
||||||
assignGlobalVar(v)
|
assignGlobalVar(p.module, v)
|
||||||
else begin
|
else begin
|
||||||
assignLocalVar(p, v);
|
assignLocalVar(p, v);
|
||||||
initVariable(p, v) // XXX: this is not required if a.sons[2] != nil,
|
initVariable(p, v) // XXX: this is not required if a.sons[2] != nil,
|
||||||
|
|
@ -95,19 +104,20 @@ var
|
||||||
begin
|
begin
|
||||||
for i := 0 to sonsLen(t)-1 do begin
|
for i := 0 to sonsLen(t)-1 do begin
|
||||||
if t.sons[i].kind = nkCommentStmt then continue;
|
if t.sons[i].kind = nkCommentStmt then continue;
|
||||||
assert(t.sons[i].kind = nkConstDef);
|
if t.sons[i].kind <> nkConstDef then InternalError(t.info, 'genConstStmt');
|
||||||
c := t.sons[i].sons[0].sym;
|
c := t.sons[i].sons[0].sym;
|
||||||
// This can happen for forward consts:
|
// This can happen for forward consts:
|
||||||
if (c.ast <> nil) and (c.typ.kind in ConstantDataTypes) and
|
if (c.ast <> nil) and (c.typ.kind in ConstantDataTypes) and
|
||||||
not (lfNoDecl in c.loc.flags) then begin
|
not (lfNoDecl in c.loc.flags) then begin
|
||||||
// generate the data:
|
// generate the data:
|
||||||
fillLoc(c.loc, locData, c.typ, mangleName(c), {@set}[lfOnData]);
|
fillLoc(c.loc, locData, c.typ, mangleName(c), OnUnknown);
|
||||||
if sfImportc in c.flags then
|
if sfImportc in c.flags then
|
||||||
appRopeFormat(currMod.s[cfsData], 'extern $1$2 $3;$n',
|
appf(p.module.s[cfsData], 'extern NIM_CONST $1 $2;$n',
|
||||||
[constTok, getTypeDesc(c.typ), c.loc.r])
|
[getTypeDesc(p.module, c.typ), c.loc.r])
|
||||||
else
|
else
|
||||||
appRopeFormat(currMod.s[cfsData], '$1$2 $3 = $4;$n',
|
appf(p.module.s[cfsData], 'NIM_CONST $1 $2 = $3;$n',
|
||||||
[constTok, getTypeDesc(c.typ), c.loc.r, genConstExpr(p, c.ast)])
|
[getTypeDesc(p.module, c.typ), c.loc.r,
|
||||||
|
genConstExpr(p, c.ast)])
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end;
|
end;
|
||||||
|
|
@ -139,11 +149,11 @@ begin
|
||||||
nkElifBranch: begin
|
nkElifBranch: begin
|
||||||
a := initLocExpr(p, it.sons[0]);
|
a := initLocExpr(p, it.sons[0]);
|
||||||
Lelse := getLabel(p);
|
Lelse := getLabel(p);
|
||||||
appRopeFormat(p.s[cpsStmts], 'if (!$1) goto $2;$n', [rdLoc(a), Lelse]);
|
appf(p.s[cpsStmts], 'if (!$1) goto $2;$n', [rdLoc(a), Lelse]);
|
||||||
freeTemp(p, a);
|
freeTemp(p, a);
|
||||||
genStmts(p, it.sons[1]);
|
genStmts(p, it.sons[1]);
|
||||||
if sonsLen(n) > 1 then
|
if sonsLen(n) > 1 then
|
||||||
appRopeFormat(p.s[cpsStmts], 'goto $1;$n', [Lend]);
|
appf(p.s[cpsStmts], 'goto $1;$n', [Lend]);
|
||||||
fixLabel(p, Lelse);
|
fixLabel(p, Lelse);
|
||||||
end;
|
end;
|
||||||
nkElse: begin
|
nkElse: begin
|
||||||
|
|
@ -166,17 +176,18 @@ var
|
||||||
begin
|
begin
|
||||||
genLineDir(p, t);
|
genLineDir(p, t);
|
||||||
assert(sonsLen(t) = 2);
|
assert(sonsLen(t) = 2);
|
||||||
inc(p.unique);
|
inc(p.labels);
|
||||||
Labl := con('L'+'', toRope(p.unique));
|
Labl := con('L'+'', toRope(p.labels));
|
||||||
len := length(p.blocks);
|
len := length(p.blocks);
|
||||||
setLength(p.blocks, len+1);
|
setLength(p.blocks, len+1);
|
||||||
p.blocks[len] := p.unique; // positive because we use it right away:
|
p.blocks[len].id := p.labels; // positive because we use it right away:
|
||||||
|
p.blocks[len].nestedTryStmts := p.nestedTryStmts;
|
||||||
app(p.s[cpsStmts], 'while (1) {' + tnl);
|
app(p.s[cpsStmts], 'while (1) {' + tnl);
|
||||||
a := initLocExpr(p, t.sons[0]);
|
a := initLocExpr(p, t.sons[0]);
|
||||||
appRopeFormat(p.s[cpsStmts], 'if (!$1) goto $2;$n', [rdLoc(a), Labl]);
|
appf(p.s[cpsStmts], 'if (!$1) goto $2;$n', [rdLoc(a), Labl]);
|
||||||
freeTemp(p, a);
|
freeTemp(p, a);
|
||||||
genStmts(p, t.sons[1]);
|
genStmts(p, t.sons[1]);
|
||||||
appRopeFormat(p.s[cpsStmts], '} $1: ;$n', [Labl]);
|
appf(p.s[cpsStmts], '} $1: ;$n', [Labl]);
|
||||||
setLength(p.blocks, length(p.blocks)-1)
|
setLength(p.blocks, length(p.blocks)-1)
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
@ -185,7 +196,7 @@ var
|
||||||
idx: int;
|
idx: int;
|
||||||
sym: PSym;
|
sym: PSym;
|
||||||
begin
|
begin
|
||||||
inc(p.unique);
|
inc(p.labels);
|
||||||
idx := length(p.blocks);
|
idx := length(p.blocks);
|
||||||
if t.sons[0] <> nil then begin // named block?
|
if t.sons[0] <> nil then begin // named block?
|
||||||
assert(t.sons[0].kind = nkSym);
|
assert(t.sons[0].kind = nkSym);
|
||||||
|
|
@ -194,14 +205,22 @@ begin
|
||||||
sym.loc.a := idx
|
sym.loc.a := idx
|
||||||
end;
|
end;
|
||||||
setLength(p.blocks, idx+1);
|
setLength(p.blocks, idx+1);
|
||||||
p.blocks[idx] := -p.unique; // negative because it isn't used yet
|
p.blocks[idx].id := -p.labels; // negative because it isn't used yet
|
||||||
|
p.blocks[idx].nestedTryStmts := p.nestedTryStmts;
|
||||||
if t.kind = nkBlockExpr then genStmtListExpr(p, t.sons[1], d)
|
if t.kind = nkBlockExpr then genStmtListExpr(p, t.sons[1], d)
|
||||||
else genStmts(p, t.sons[1]);
|
else genStmts(p, t.sons[1]);
|
||||||
if p.blocks[idx] > 0 then // label has been used:
|
if p.blocks[idx].id > 0 then // label has been used:
|
||||||
appRopeFormat(p.s[cpsStmts], 'L$1: ;$n', [toRope(p.blocks[idx])]);
|
appf(p.s[cpsStmts], 'L$1: ;$n', [toRope(p.blocks[idx].id)]);
|
||||||
setLength(p.blocks, idx)
|
setLength(p.blocks, idx)
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
// try:
|
||||||
|
// while:
|
||||||
|
// try:
|
||||||
|
// if ...:
|
||||||
|
// break # we need to finish only one try statement here!
|
||||||
|
// finally:
|
||||||
|
|
||||||
procedure genBreakStmt(p: BProc; t: PNode);
|
procedure genBreakStmt(p: BProc; t: PNode);
|
||||||
var
|
var
|
||||||
idx: int;
|
idx: int;
|
||||||
|
|
@ -215,8 +234,9 @@ begin
|
||||||
assert(sym.loc.k = locOther);
|
assert(sym.loc.k = locOther);
|
||||||
idx := sym.loc.a
|
idx := sym.loc.a
|
||||||
end;
|
end;
|
||||||
p.blocks[idx] := abs(p.blocks[idx]); // label is used
|
p.blocks[idx].id := abs(p.blocks[idx].id); // label is used
|
||||||
appRopeFormat(p.s[cpsStmts], 'goto L$1;$n', [toRope(p.blocks[idx])])
|
finishTryStmt(p, p.nestedTryStmts - p.blocks[idx].nestedTryStmts);
|
||||||
|
appf(p.s[cpsStmts], 'goto L$1;$n', [toRope(p.blocks[idx].id)])
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure genAsmStmt(p: BProc; t: PNode);
|
procedure genAsmStmt(p: BProc; t: PNode);
|
||||||
|
|
@ -245,15 +265,15 @@ begin
|
||||||
InternalError(t.sons[i].info, 'genAsmStmt()')
|
InternalError(t.sons[i].info, 'genAsmStmt()')
|
||||||
end
|
end
|
||||||
end;
|
end;
|
||||||
appRopeFormat(p.s[cpsStmts], CC[ccompiler].asmStmtFrmt, [s]);
|
appf(p.s[cpsStmts], CC[ccompiler].asmStmtFrmt, [s]);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function getRaiseFrmt(): string;
|
function getRaiseFrmt(p: BProc): string;
|
||||||
begin
|
begin
|
||||||
if gCmd = cmdCompileToCpp then
|
if gCmd = cmdCompileToCpp then
|
||||||
result := 'throw nimException($1, $2);$n'
|
result := 'throw nimException($1, $2);$n'
|
||||||
else begin
|
else begin
|
||||||
useMagic('E_Base');
|
useMagic(p.module, 'E_Base');
|
||||||
result := 'raiseException((E_Base*)$1, $2);$n'
|
result := 'raiseException((E_Base*)$1, $2);$n'
|
||||||
end
|
end
|
||||||
end;
|
end;
|
||||||
|
|
@ -266,14 +286,13 @@ var
|
||||||
begin
|
begin
|
||||||
genLineDir(p, t);
|
genLineDir(p, t);
|
||||||
if t.sons[0] <> nil then begin
|
if t.sons[0] <> nil then begin
|
||||||
if gCmd <> cmdCompileToCpp then
|
if gCmd <> cmdCompileToCpp then useMagic(p.module, 'raiseException');
|
||||||
useMagic('raiseException');
|
|
||||||
a := InitLocExpr(p, t.sons[0]);
|
a := InitLocExpr(p, t.sons[0]);
|
||||||
e := rdLoc(a);
|
e := rdLoc(a);
|
||||||
freeTemp(p, a);
|
freeTemp(p, a);
|
||||||
typ := t.sons[0].typ;
|
typ := t.sons[0].typ;
|
||||||
while typ.kind in [tyVar, tyRef, tyPtr] do typ := typ.sons[0];
|
while typ.kind in [tyVar, tyRef, tyPtr] do typ := typ.sons[0];
|
||||||
appRopeFormat(p.s[cpsStmts], getRaiseFrmt(),
|
appf(p.s[cpsStmts], getRaiseFrmt(p),
|
||||||
[e, makeCString(typ.sym.name.s)])
|
[e, makeCString(typ.sym.name.s)])
|
||||||
end
|
end
|
||||||
else begin
|
else begin
|
||||||
|
|
@ -281,7 +300,7 @@ begin
|
||||||
if gCmd = cmdCompileToCpp then
|
if gCmd = cmdCompileToCpp then
|
||||||
app(p.s[cpsStmts], 'throw;' + tnl)
|
app(p.s[cpsStmts], 'throw;' + tnl)
|
||||||
else begin
|
else begin
|
||||||
useMagic('reraiseException');
|
useMagic(p.module, 'reraiseException');
|
||||||
app(p.s[cpsStmts], 'reraiseException();' + tnl)
|
app(p.s[cpsStmts], 'reraiseException();' + tnl)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
@ -309,13 +328,13 @@ begin
|
||||||
y := initLocExpr(p, b.sons[i].sons[1]);
|
y := initLocExpr(p, b.sons[i].sons[1]);
|
||||||
freeTemp(p, x);
|
freeTemp(p, x);
|
||||||
freeTemp(p, y);
|
freeTemp(p, y);
|
||||||
appRopeFormat(p.s[cpsStmts], rangeFormat,
|
appf(p.s[cpsStmts], rangeFormat,
|
||||||
[rdCharLoc(e), rdCharLoc(x), rdCharLoc(y), labl])
|
[rdCharLoc(e), rdCharLoc(x), rdCharLoc(y), labl])
|
||||||
end
|
end
|
||||||
else begin
|
else begin
|
||||||
x := initLocExpr(p, b.sons[i]);
|
x := initLocExpr(p, b.sons[i]);
|
||||||
freeTemp(p, x);
|
freeTemp(p, x);
|
||||||
appRopeFormat(p.s[cpsStmts], eqFormat,
|
appf(p.s[cpsStmts], eqFormat,
|
||||||
[rdCharLoc(e), rdCharLoc(x), labl])
|
[rdCharLoc(e), rdCharLoc(x), labl])
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
@ -328,11 +347,11 @@ var
|
||||||
begin
|
begin
|
||||||
Lend := getLabel(p);
|
Lend := getLabel(p);
|
||||||
for i := 1 to sonsLen(t) - 1 do begin
|
for i := 1 to sonsLen(t) - 1 do begin
|
||||||
appRopeFormat(p.s[cpsStmts], 'L$1: ;$n', [toRope(labId+i)]);
|
appf(p.s[cpsStmts], 'L$1: ;$n', [toRope(labId+i)]);
|
||||||
if t.sons[i].kind = nkOfBranch then begin
|
if t.sons[i].kind = nkOfBranch then begin
|
||||||
len := sonsLen(t.sons[i]);
|
len := sonsLen(t.sons[i]);
|
||||||
genStmts(p, t.sons[i].sons[len-1]);
|
genStmts(p, t.sons[i].sons[len-1]);
|
||||||
appRopeFormat(p.s[cpsStmts], 'goto $1;$n', [Lend])
|
appf(p.s[cpsStmts], 'goto $1;$n', [Lend])
|
||||||
end
|
end
|
||||||
else // else statement
|
else // else statement
|
||||||
genStmts(p, t.sons[i].sons[0])
|
genStmts(p, t.sons[i].sons[0])
|
||||||
|
|
@ -349,15 +368,15 @@ var
|
||||||
begin
|
begin
|
||||||
a := initLocExpr(p, t.sons[0]);
|
a := initLocExpr(p, t.sons[0]);
|
||||||
// fist pass: gnerate ifs+goto:
|
// fist pass: gnerate ifs+goto:
|
||||||
labId := p.unique;
|
labId := p.labels;
|
||||||
for i := 1 to sonsLen(t) - 1 do begin
|
for i := 1 to sonsLen(t) - 1 do begin
|
||||||
inc(p.unique);
|
inc(p.labels);
|
||||||
if t.sons[i].kind = nkOfBranch then
|
if t.sons[i].kind = nkOfBranch then
|
||||||
genCaseGenericBranch(p, t.sons[i], a, rangeFormat, eqFormat,
|
genCaseGenericBranch(p, t.sons[i], a, rangeFormat, eqFormat,
|
||||||
con('L'+'', toRope(p.unique)))
|
con('L'+'', toRope(p.labels)))
|
||||||
else
|
else
|
||||||
// else statement
|
// else statement
|
||||||
appRopeFormat(p.s[cpsStmts], 'goto L$1;$n', [toRope(p.unique)]);
|
appf(p.s[cpsStmts], 'goto L$1;$n', [toRope(p.labels)]);
|
||||||
end;
|
end;
|
||||||
// second pass: generate statements
|
// second pass: generate statements
|
||||||
genCaseSecondPass(p, t, labId);
|
genCaseSecondPass(p, t, labId);
|
||||||
|
|
@ -435,7 +454,7 @@ begin
|
||||||
freeTemp(p, x);
|
freeTemp(p, x);
|
||||||
assert(b.sons[i].kind in [nkStrLit..nkTripleStrLit]);
|
assert(b.sons[i].kind in [nkStrLit..nkTripleStrLit]);
|
||||||
j := int(hashString(b.sons[i].strVal) and high(branches));
|
j := int(hashString(b.sons[i].strVal) and high(branches));
|
||||||
appRopeFormat(branches[j], 'if (eqStrings($1, $2)) goto $3;$n',
|
appf(branches[j], 'if (eqStrings($1, $2)) goto $3;$n',
|
||||||
[rdLoc(e), rdLoc(x), labl])
|
[rdLoc(e), rdLoc(x), labl])
|
||||||
end
|
end
|
||||||
end;
|
end;
|
||||||
|
|
@ -446,38 +465,39 @@ var
|
||||||
a: TLoc;
|
a: TLoc;
|
||||||
branches: TRopeSeq;
|
branches: TRopeSeq;
|
||||||
begin
|
begin
|
||||||
useMagic('eqStrings');
|
useMagic(p.module, 'eqStrings');
|
||||||
// count how many constant strings there are in the case:
|
// count how many constant strings there are in the case:
|
||||||
strings := 0;
|
strings := 0;
|
||||||
for i := 1 to sonsLen(t)-1 do
|
for i := 1 to sonsLen(t)-1 do
|
||||||
if t.sons[i].kind = nkOfBranch then inc(strings, sonsLen(t.sons[i])-1);
|
if t.sons[i].kind = nkOfBranch then inc(strings, sonsLen(t.sons[i])-1);
|
||||||
if strings > stringCaseThreshold then begin
|
if strings > stringCaseThreshold then begin
|
||||||
useMagic('hashString');
|
useMagic(p.module, 'hashString');
|
||||||
bitMask := nmath.nextPowerOfTwo(strings)-1;
|
bitMask := nmath.nextPowerOfTwo(strings)-1;
|
||||||
setLength(branches, bitMask+1);
|
setLength(branches, bitMask+1);
|
||||||
a := initLocExpr(p, t.sons[0]);
|
a := initLocExpr(p, t.sons[0]);
|
||||||
// fist pass: gnerate ifs+goto:
|
// fist pass: gnerate ifs+goto:
|
||||||
labId := p.unique;
|
labId := p.labels;
|
||||||
for i := 1 to sonsLen(t) - 1 do begin
|
for i := 1 to sonsLen(t) - 1 do begin
|
||||||
inc(p.unique);
|
inc(p.labels);
|
||||||
if t.sons[i].kind = nkOfBranch then
|
if t.sons[i].kind = nkOfBranch then
|
||||||
genCaseStringBranch(p, t.sons[i], a, con('L'+'', toRope(p.unique)),
|
genCaseStringBranch(p, t.sons[i], a, con('L'+'', toRope(p.labels)),
|
||||||
branches)
|
branches)
|
||||||
else begin end
|
else begin
|
||||||
// else statement: nothing to do yet
|
// else statement: nothing to do yet
|
||||||
// but we reserved a label, which we use later
|
// but we reserved a label, which we use later
|
||||||
|
end
|
||||||
end;
|
end;
|
||||||
// second pass: generate switch statement based on hash of string:
|
// second pass: generate switch statement based on hash of string:
|
||||||
appRopeFormat(p.s[cpsStmts], 'switch (hashString($1) & $2) {$n',
|
appf(p.s[cpsStmts], 'switch (hashString($1) & $2) {$n',
|
||||||
[rdLoc(a), toRope(bitMask)]);
|
[rdLoc(a), toRope(bitMask)]);
|
||||||
for j := 0 to high(branches) do
|
for j := 0 to high(branches) do
|
||||||
if branches[j] <> nil then
|
if branches[j] <> nil then
|
||||||
appRopeFormat(p.s[cpsStmts], 'case $1: $n$2break;$n',
|
appf(p.s[cpsStmts], 'case $1: $n$2break;$n',
|
||||||
[intLiteral(j), branches[j]]);
|
[intLiteral(j), branches[j]]);
|
||||||
app(p.s[cpsStmts], '}' + tnl);
|
app(p.s[cpsStmts], '}' + tnl);
|
||||||
// else statement:
|
// else statement:
|
||||||
if t.sons[sonsLen(t)-1].kind <> nkOfBranch then
|
if t.sons[sonsLen(t)-1].kind <> nkOfBranch then
|
||||||
appRopeFormat(p.s[cpsStmts], 'goto L$1;$n', [toRope(p.unique)]);
|
appf(p.s[cpsStmts], 'goto L$1;$n', [toRope(p.labels)]);
|
||||||
// third pass: generate statements
|
// third pass: generate statements
|
||||||
genCaseSecondPass(p, t, labId);
|
genCaseSecondPass(p, t, labId);
|
||||||
freeTemp(p, a);
|
freeTemp(p, a);
|
||||||
|
|
@ -521,7 +541,7 @@ begin
|
||||||
end;
|
end;
|
||||||
if canGenerateSwitch then begin
|
if canGenerateSwitch then begin
|
||||||
a := initLocExpr(p, t.sons[0]);
|
a := initLocExpr(p, t.sons[0]);
|
||||||
appRopeFormat(p.s[cpsStmts], 'switch ($1) {$n', [rdCharLoc(a)]);
|
appf(p.s[cpsStmts], 'switch ($1) {$n', [rdCharLoc(a)]);
|
||||||
freeTemp(p, a);
|
freeTemp(p, a);
|
||||||
for i := 1 to sonsLen(t)-1 do begin
|
for i := 1 to sonsLen(t)-1 do begin
|
||||||
if t.sons[i].kind = nkOfBranch then begin
|
if t.sons[i].kind = nkOfBranch then begin
|
||||||
|
|
@ -529,19 +549,19 @@ begin
|
||||||
for j := 0 to len-2 do begin
|
for j := 0 to len-2 do begin
|
||||||
if t.sons[i].sons[j].kind = nkRange then begin // a range
|
if t.sons[i].sons[j].kind = nkRange then begin // a range
|
||||||
if hasSwitchRange in CC[ccompiler].props then
|
if hasSwitchRange in CC[ccompiler].props then
|
||||||
appRopeFormat(p.s[cpsStmts], 'case $1 ... $2:$n',
|
appf(p.s[cpsStmts], 'case $1 ... $2:$n',
|
||||||
[genLiteral(p, t.sons[i].sons[j].sons[0]),
|
[genLiteral(p, t.sons[i].sons[j].sons[0]),
|
||||||
genLiteral(p, t.sons[i].sons[j].sons[1])])
|
genLiteral(p, t.sons[i].sons[j].sons[1])])
|
||||||
else begin
|
else begin
|
||||||
v := copyNode(t.sons[i].sons[j].sons[0]);
|
v := copyNode(t.sons[i].sons[j].sons[0]);
|
||||||
while (v.intVal <= t.sons[i].sons[j].sons[1].intVal) do begin
|
while (v.intVal <= t.sons[i].sons[j].sons[1].intVal) do begin
|
||||||
appRopeFormat(p.s[cpsStmts], 'case $1:$n', [genLiteral(p, v)]);
|
appf(p.s[cpsStmts], 'case $1:$n', [genLiteral(p, v)]);
|
||||||
Inc(v.intVal)
|
Inc(v.intVal)
|
||||||
end
|
end
|
||||||
end;
|
end;
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
appRopeFormat(p.s[cpsStmts], 'case $1:$n',
|
appf(p.s[cpsStmts], 'case $1:$n',
|
||||||
[genLiteral(p, t.sons[i].sons[j])]);
|
[genLiteral(p, t.sons[i].sons[j])]);
|
||||||
end;
|
end;
|
||||||
genStmts(p, t.sons[i].sons[len-1])
|
genStmts(p, t.sons[i].sons[len-1])
|
||||||
|
|
@ -563,7 +583,7 @@ end;
|
||||||
procedure genCaseStmt(p: BProc; t: PNode);
|
procedure genCaseStmt(p: BProc; t: PNode);
|
||||||
begin
|
begin
|
||||||
genLineDir(p, t);
|
genLineDir(p, t);
|
||||||
case skipAbstract(t.sons[0].typ).kind of
|
case skipVarGenericRange(t.sons[0].typ).kind of
|
||||||
tyString: genStringCase(p, t);
|
tyString: genStringCase(p, t);
|
||||||
tyFloat..tyFloat128:
|
tyFloat..tyFloat128:
|
||||||
genCaseGeneric(p, t, 'if ($1 >= $2 && $1 <= $3) goto $4;$n',
|
genCaseGeneric(p, t, 'if ($1 >= $2 && $1 <= $3) goto $4;$n',
|
||||||
|
|
@ -622,21 +642,20 @@ begin
|
||||||
exc := getTempName();
|
exc := getTempName();
|
||||||
if not hasGeneralExceptSection(t) then begin
|
if not hasGeneralExceptSection(t) then begin
|
||||||
rethrowFlag := getTempName();
|
rethrowFlag := getTempName();
|
||||||
appRopeFormat(p.s[cpsLocals], 'volatile NIM_BOOL $1 = NIM_FALSE;$n',
|
appf(p.s[cpsLocals], 'volatile NIM_BOOL $1 = NIM_FALSE;$n',
|
||||||
[rethrowFlag])
|
[rethrowFlag])
|
||||||
end;
|
end;
|
||||||
if optStackTrace in p.Options then
|
if optStackTrace in p.Options then
|
||||||
app(p.s[cpsStmts], 'framePtr = (TFrame*)&F;' + tnl);
|
app(p.s[cpsStmts], 'framePtr = (TFrame*)&F;' + tnl);
|
||||||
app(p.s[cpsStmts], 'try {' + tnl);
|
app(p.s[cpsStmts], 'try {' + tnl);
|
||||||
inc(p.inTryStmt);
|
inc(p.nestedTryStmts);
|
||||||
genStmts(p, t.sons[0]);
|
genStmts(p, t.sons[0]);
|
||||||
dec(p.inTryStmt);
|
|
||||||
len := sonsLen(t);
|
len := sonsLen(t);
|
||||||
if t.sons[1].kind = nkExceptBranch then begin
|
if t.sons[1].kind = nkExceptBranch then begin
|
||||||
appRopeFormat(p.s[cpsStmts], '} catch (NimException& $1) {$n', [exc]);
|
appf(p.s[cpsStmts], '} catch (NimException& $1) {$n', [exc]);
|
||||||
if rethrowFlag <> nil then
|
if rethrowFlag <> nil then
|
||||||
appRopeFormat(p.s[cpsStmts], '$1 = NIM_TRUE;$n', [rethrowFlag]);
|
appf(p.s[cpsStmts], '$1 = NIM_TRUE;$n', [rethrowFlag]);
|
||||||
appRopeFormat(p.s[cpsStmts], 'if ($1.sp.exc) {$n', [exc])
|
appf(p.s[cpsStmts], 'if ($1.sp.exc) {$n', [exc])
|
||||||
end; // XXX: this is not correct!
|
end; // XXX: this is not correct!
|
||||||
i := 1;
|
i := 1;
|
||||||
while (i < len) and (t.sons[i].kind = nkExceptBranch) do begin
|
while (i < len) and (t.sons[i].kind = nkExceptBranch) do begin
|
||||||
|
|
@ -648,24 +667,25 @@ begin
|
||||||
else begin
|
else begin
|
||||||
for j := 0 to blen - 2 do begin
|
for j := 0 to blen - 2 do begin
|
||||||
assert(t.sons[i].sons[j].kind = nkType);
|
assert(t.sons[i].sons[j].kind = nkType);
|
||||||
appRopeFormat(p.s[cpsStmts], 'case $1:$n',
|
appf(p.s[cpsStmts], 'case $1:$n',
|
||||||
[toRope(t.sons[i].sons[j].typ.id)])
|
[toRope(t.sons[i].sons[j].typ.id)])
|
||||||
end;
|
end;
|
||||||
genStmts(p, t.sons[i].sons[blen - 1])
|
genStmts(p, t.sons[i].sons[blen - 1])
|
||||||
end;
|
end;
|
||||||
// code to clear the exception:
|
// code to clear the exception:
|
||||||
if rethrowFlag <> nil then
|
if rethrowFlag <> nil then
|
||||||
appRopeFormat(p.s[cpsStmts], '$1 = NIM_FALSE; ', [rethrowFlag]);
|
appf(p.s[cpsStmts], '$1 = NIM_FALSE; ', [rethrowFlag]);
|
||||||
app(p.s[cpsStmts], 'break;' + tnl);
|
app(p.s[cpsStmts], 'break;' + tnl);
|
||||||
inc(i);
|
inc(i);
|
||||||
end;
|
end;
|
||||||
if t.sons[1].kind = nkExceptBranch then // BUGFIX
|
if t.sons[1].kind = nkExceptBranch then // BUGFIX
|
||||||
app(p.s[cpsStmts], '}}' + tnl); // end of catch-switch statement
|
app(p.s[cpsStmts], '}}' + tnl); // end of catch-switch statement
|
||||||
|
dec(p.nestedTryStmts);
|
||||||
app(p.s[cpsStmts], 'excHandler = excHandler->prev;' + tnl);
|
app(p.s[cpsStmts], 'excHandler = excHandler->prev;' + tnl);
|
||||||
if (i < len) and (t.sons[i].kind = nkFinally) then begin
|
if (i < len) and (t.sons[i].kind = nkFinally) then begin
|
||||||
genStmts(p, t.sons[i].sons[0]);
|
genStmts(p, t.sons[i].sons[0]);
|
||||||
if rethrowFlag <> nil then
|
if rethrowFlag <> nil then
|
||||||
appRopeFormat(p.s[cpsStmts], 'if ($1) { throw; }$n', [rethrowFlag])
|
appf(p.s[cpsStmts], 'if ($1) { throw; }$n', [rethrowFlag])
|
||||||
end
|
end
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
@ -698,21 +718,21 @@ begin
|
||||||
genLineDir(p, t);
|
genLineDir(p, t);
|
||||||
|
|
||||||
safePoint := getTempName();
|
safePoint := getTempName();
|
||||||
useMagic('TSafePoint');
|
useMagic(p.module, 'TSafePoint');
|
||||||
useMagic('E_Base');
|
useMagic(p.module, 'E_Base');
|
||||||
useMagic('excHandler');
|
useMagic(p.module, 'excHandler');
|
||||||
appRopeFormat(p.s[cpsLocals], 'volatile TSafePoint $1;$n', [safePoint]);
|
appf(p.s[cpsLocals], 'TSafePoint $1;$n', [safePoint]);
|
||||||
appRopeFormat(p.s[cpsStmts], '$1.prev = excHandler;$n' +
|
appf(p.s[cpsStmts], '$1.prev = excHandler;$n' +
|
||||||
'excHandler = &$1;$n' +
|
'excHandler = &$1;$n' +
|
||||||
'$1.status = setjmp($1.context);$n' +
|
'$1.status = setjmp($1.context);$n',
|
||||||
'if ($1.status == 0) {$n', [safePoint]);
|
[safePoint]);
|
||||||
if optStackTrace in p.Options then
|
if optStackTrace in p.Options then
|
||||||
app(p.s[cpsStmts], 'framePtr = (TFrame*)&F;' + tnl);
|
app(p.s[cpsStmts], 'framePtr = (TFrame*)&F;' + tnl);
|
||||||
|
appf(p.s[cpsStmts], 'if ($1.status == 0) {$n', [safePoint]);
|
||||||
len := sonsLen(t);
|
len := sonsLen(t);
|
||||||
inc(p.inTryStmt);
|
inc(p.nestedTryStmts);
|
||||||
genStmts(p, t.sons[0]);
|
genStmts(p, t.sons[0]);
|
||||||
app(p.s[cpsStmts], '} else {' + tnl);
|
app(p.s[cpsStmts], '} else {' + tnl);
|
||||||
dec(p.inTryStmt);
|
|
||||||
i := 1;
|
i := 1;
|
||||||
while (i < len) and (t.sons[i].kind = nkExceptBranch) do begin
|
while (i < len) and (t.sons[i].kind = nkExceptBranch) do begin
|
||||||
blen := sonsLen(t.sons[i]);
|
blen := sonsLen(t.sons[i]);
|
||||||
|
|
@ -720,7 +740,7 @@ begin
|
||||||
// general except section:
|
// general except section:
|
||||||
if i > 1 then app(p.s[cpsStmts], 'else {' + tnl);
|
if i > 1 then app(p.s[cpsStmts], 'else {' + tnl);
|
||||||
genStmts(p, t.sons[i].sons[0]);
|
genStmts(p, t.sons[i].sons[0]);
|
||||||
appRopeFormat(p.s[cpsStmts], '$1.status = 0;$n', [safePoint]);
|
appf(p.s[cpsStmts], '$1.status = 0;$n', [safePoint]);
|
||||||
if i > 1 then app(p.s[cpsStmts], '}' + tnl);
|
if i > 1 then app(p.s[cpsStmts], '}' + tnl);
|
||||||
end
|
end
|
||||||
else begin
|
else begin
|
||||||
|
|
@ -728,24 +748,25 @@ begin
|
||||||
for j := 0 to blen - 2 do begin
|
for j := 0 to blen - 2 do begin
|
||||||
assert(t.sons[i].sons[j].kind = nkType);
|
assert(t.sons[i].sons[j].kind = nkType);
|
||||||
if orExpr <> nil then app(orExpr, '||');
|
if orExpr <> nil then app(orExpr, '||');
|
||||||
appRopeFormat(orExpr, '($1.exc->Sup.m_type == $2)',
|
appf(orExpr, '($1.exc->Sup.m_type == $2)',
|
||||||
[safePoint, genTypeInfo(currMod, t.sons[i].sons[j].typ)])
|
[safePoint, genTypeInfo(p.module, t.sons[i].sons[j].typ)])
|
||||||
end;
|
end;
|
||||||
if i > 1 then app(p.s[cpsStmts], 'else ');
|
if i > 1 then app(p.s[cpsStmts], 'else ');
|
||||||
appRopeFormat(p.s[cpsStmts], 'if ($1) {$n', [orExpr]);
|
appf(p.s[cpsStmts], 'if ($1) {$n', [orExpr]);
|
||||||
genStmts(p, t.sons[i].sons[blen - 1]);
|
genStmts(p, t.sons[i].sons[blen - 1]);
|
||||||
// code to clear the exception:
|
// code to clear the exception:
|
||||||
appRopeFormat(p.s[cpsStmts], '$1.status = 0;}$n', [safePoint]);
|
appf(p.s[cpsStmts], '$1.status = 0;}$n', [safePoint]);
|
||||||
end;
|
end;
|
||||||
inc(i)
|
inc(i)
|
||||||
end;
|
end;
|
||||||
app(p.s[cpsStmts], '}' + tnl); // end of if statement
|
app(p.s[cpsStmts], '}' + tnl); // end of if statement
|
||||||
app(p.s[cpsStmts], 'excHandler = excHandler->prev;' + tnl);
|
finishTryStmt(p, p.nestedTryStmts);
|
||||||
|
dec(p.nestedTryStmts);
|
||||||
if (i < len) and (t.sons[i].kind = nkFinally) then begin
|
if (i < len) and (t.sons[i].kind = nkFinally) then begin
|
||||||
genStmts(p, t.sons[i].sons[0]);
|
genStmts(p, t.sons[i].sons[0]);
|
||||||
useMagic('raiseException');
|
useMagic(p.module, 'raiseException');
|
||||||
appRopeFormat(p.s[cpsStmts], 'if ($1.status != 0) { ' +
|
appf(p.s[cpsStmts], 'if ($1.status != 0) { ' +
|
||||||
'raiseException($1.exc, $1.exc->Name); }$n', [safePoint])
|
'raiseException($1.exc, $1.exc->name); }$n', [safePoint])
|
||||||
end
|
end
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
@ -767,7 +788,7 @@ begin
|
||||||
name := 'bp' + toString(breakPointId)
|
name := 'bp' + toString(breakPointId)
|
||||||
end;
|
end;
|
||||||
genLineDir(p, t); // BUGFIX
|
genLineDir(p, t); // BUGFIX
|
||||||
appRopeFormat(gBreakpoints,
|
appf(gBreakpoints,
|
||||||
'dbgRegisterBreakpoint($1, (NCSTRING)$2, (NCSTRING)$3);$n',
|
'dbgRegisterBreakpoint($1, (NCSTRING)$2, (NCSTRING)$3);$n',
|
||||||
[toRope(toLinenumber(t.info)), makeCString(toFilename(t.info)),
|
[toRope(toLinenumber(t.info)), makeCString(toFilename(t.info)),
|
||||||
makeCString(name)])
|
makeCString(name)])
|
||||||
|
|
@ -852,15 +873,15 @@ begin
|
||||||
nkCommentStmt, nkNilLit, nkIteratorDef, nkIncludeStmt, nkImportStmt,
|
nkCommentStmt, nkNilLit, nkIteratorDef, nkIncludeStmt, nkImportStmt,
|
||||||
nkFromStmt, nkTemplateDef, nkMacroDef: begin end;
|
nkFromStmt, nkTemplateDef, nkMacroDef: begin end;
|
||||||
nkPragma: genPragma(p, t);
|
nkPragma: genPragma(p, t);
|
||||||
nkProcDef: begin
|
nkProcDef, nkConverterDef: begin
|
||||||
if (t.sons[genericParamsPos] = nil) then begin
|
if (t.sons[genericParamsPos] = nil) then begin
|
||||||
prc := t.sons[namePos].sym;
|
prc := t.sons[namePos].sym;
|
||||||
if (t.sons[codePos] <> nil)
|
if (t.sons[codePos] <> nil)
|
||||||
or (lfDynamicLib in prc.loc.flags) then begin // BUGFIX
|
or (lfDynamicLib in prc.loc.flags) then begin // BUGFIX
|
||||||
if IntSetContainsOrIncl(currMod.debugDeclared, prc.id) then begin
|
if IntSetContainsOrIncl(p.module.debugDeclared, prc.id) then begin
|
||||||
internalError(t.info, 'genProc()'); // XXX: remove this check!
|
internalError(t.info, 'genProc()'); // XXX: remove this check!
|
||||||
end;
|
end;
|
||||||
genProc(prc)
|
genProc(p.module, prc)
|
||||||
end
|
end
|
||||||
//else if sfCompilerProc in prc.flags then genProcPrototype(prc);
|
//else if sfCompilerProc in prc.flags then genProcPrototype(prc);
|
||||||
end
|
end
|
||||||
|
|
|
||||||
559
nim/ccgtypes.pas
559
nim/ccgtypes.pas
|
|
@ -9,12 +9,6 @@
|
||||||
|
|
||||||
// ------------------------- Name Mangling --------------------------------
|
// ------------------------- Name Mangling --------------------------------
|
||||||
|
|
||||||
function getUnique(p: BProc): PRope;
|
|
||||||
begin
|
|
||||||
inc(p.unique);
|
|
||||||
result := toRope(p.unique)
|
|
||||||
end;
|
|
||||||
|
|
||||||
function mangle(const name: string): string;
|
function mangle(const name: string): string;
|
||||||
var
|
var
|
||||||
i: int;
|
i: int;
|
||||||
|
|
@ -23,7 +17,7 @@ begin
|
||||||
result := toUpper(name[strStart])+''
|
result := toUpper(name[strStart])+''
|
||||||
else
|
else
|
||||||
result := 'HEX' + toHex(ord(name[strStart]), 2);
|
result := 'HEX' + toHex(ord(name[strStart]), 2);
|
||||||
for i := 2 to length(name) - 1 + strStart do begin
|
for i := strStart+1 to length(name) + strStart-1 do begin
|
||||||
case name[i] of
|
case name[i] of
|
||||||
'A'..'Z': addChar(result, chr(ord(name[i]) - ord('A') + ord('a')));
|
'A'..'Z': addChar(result, chr(ord(name[i]) - ord('A') + ord('a')));
|
||||||
'_': begin end;
|
'_': begin end;
|
||||||
|
|
@ -35,22 +29,68 @@ end;
|
||||||
|
|
||||||
function mangleName(s: PSym): PRope;
|
function mangleName(s: PSym): PRope;
|
||||||
begin
|
begin
|
||||||
if s.owner <> nil then
|
result := ropef('$1_$2', [toRope(mangle(s.name.s)), toRope(s.id)]);
|
||||||
result := ropeFormat('$1_$2_$3', [toRope(mangle(s.owner.name.s)),
|
|
||||||
toRope(mangle(s.name.s)),
|
|
||||||
toRope(s.id)])
|
|
||||||
else
|
|
||||||
result := ropeFormat('$1_$2', [toRope(mangle(s.name.s)),
|
|
||||||
toRope(s.id)]);
|
|
||||||
if optGenMapping in gGlobalOptions then
|
if optGenMapping in gGlobalOptions then
|
||||||
if s.owner <> nil then
|
if s.owner <> nil then
|
||||||
appRopeFormat(gMapping, '$1.$2 $3$n',
|
appf(gMapping, '$1.$2 $3$n',
|
||||||
[toRope(s.owner.Name.s), toRope(s.name.s), result])
|
[toRope(s.owner.Name.s), toRope(s.name.s), result])
|
||||||
end;
|
end;
|
||||||
|
|
||||||
// ------------------------------ C type generator ------------------------
|
// ------------------------------ C type generator ------------------------
|
||||||
|
|
||||||
function getTypeDesc(typ: PType): PRope; forward;
|
function mapType(typ: PType): TCTypeKind;
|
||||||
|
begin
|
||||||
|
case typ.kind of
|
||||||
|
tyNone: result := ctVoid;
|
||||||
|
tyBool: result := ctBool;
|
||||||
|
tyChar: result := ctChar;
|
||||||
|
tyEmptySet, tySet: begin
|
||||||
|
case int(getSize(typ)) of
|
||||||
|
1: result := ctInt8;
|
||||||
|
2: result := ctInt16;
|
||||||
|
4: result := ctInt32;
|
||||||
|
8: result := ctInt64;
|
||||||
|
else result := ctArray
|
||||||
|
end
|
||||||
|
end;
|
||||||
|
tyOpenArray, tyArrayConstr, tyArray: result := ctArray;
|
||||||
|
tyObject, tyTuple: result := ctStruct;
|
||||||
|
tyGeneric, tyGenericInst, tyGenericParam: result := mapType(lastSon(typ));
|
||||||
|
tyEnum, tyAnyEnum: begin
|
||||||
|
if firstOrd(typ) < 0 then
|
||||||
|
result := ctInt32
|
||||||
|
else begin
|
||||||
|
case int(getSize(typ)) of
|
||||||
|
1: result := ctUInt8;
|
||||||
|
2: result := ctUInt16;
|
||||||
|
4: result := ctInt32;
|
||||||
|
else internalError('mapType');
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end;
|
||||||
|
tyRange: result := mapType(typ.sons[0]);
|
||||||
|
tyPtr, tyVar, tyRef: begin
|
||||||
|
case typ.sons[0].kind of
|
||||||
|
tyOpenArray, tyArrayConstr, tyArray: result := ctArray;
|
||||||
|
(*tySet: begin
|
||||||
|
if mapType(typ.sons[0]) = ctArray then result := ctArray
|
||||||
|
else result := ctPtr
|
||||||
|
end*)
|
||||||
|
else result := ctPtr
|
||||||
|
end
|
||||||
|
end;
|
||||||
|
tyPointer: result := ctPtr;
|
||||||
|
tySequence: result := ctNimSeq;
|
||||||
|
tyProc: result := ctProc;
|
||||||
|
tyString: result := ctNimStr;
|
||||||
|
tyCString: result := ctCString;
|
||||||
|
tyInt..tyFloat128:
|
||||||
|
result := TCTypeKind(ord(typ.kind) - ord(tyInt) + ord(ctInt));
|
||||||
|
else InternalError('mapType');
|
||||||
|
end
|
||||||
|
end;
|
||||||
|
|
||||||
|
function getTypeDesc(m: BModule; typ: PType): PRope; forward;
|
||||||
|
|
||||||
function needsComplexAssignment(typ: PType): bool;
|
function needsComplexAssignment(typ: PType): bool;
|
||||||
begin
|
begin
|
||||||
|
|
@ -58,8 +98,6 @@ begin
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function isInvalidReturnType(rettype: PType): bool;
|
function isInvalidReturnType(rettype: PType): bool;
|
||||||
var
|
|
||||||
t: PType;
|
|
||||||
begin
|
begin
|
||||||
// Arrays and sets cannot be returned by a C procedure, because C is
|
// Arrays and sets cannot be returned by a C procedure, because C is
|
||||||
// such a poor programming language.
|
// such a poor programming language.
|
||||||
|
|
@ -68,16 +106,9 @@ begin
|
||||||
if rettype = nil then
|
if rettype = nil then
|
||||||
result := true
|
result := true
|
||||||
else begin
|
else begin
|
||||||
t := skipAbstract(rettype);
|
case mapType(rettype) of
|
||||||
case t.kind of
|
ctArray: result := true;
|
||||||
tyArray, tyArrayConstr: result := true;
|
ctStruct: result := needsComplexAssignment(skipGeneric(rettype));
|
||||||
tyObject, tyRecord: result := needsComplexAssignment(t);
|
|
||||||
tySet: begin
|
|
||||||
case int(getSize(t)) of
|
|
||||||
1, 2, 4, 8: result := false;
|
|
||||||
else result := true
|
|
||||||
end
|
|
||||||
end
|
|
||||||
else result := false;
|
else result := false;
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
@ -96,65 +127,46 @@ begin
|
||||||
result := PRope(TableGetType(tab, key))
|
result := PRope(TableGetType(tab, key))
|
||||||
end;
|
end;
|
||||||
|
|
||||||
var
|
|
||||||
gUnique: int;
|
|
||||||
|
|
||||||
function getTempName(): PRope;
|
function getTempName(): PRope;
|
||||||
begin
|
begin
|
||||||
inc(gUnique);
|
inc(gUnique);
|
||||||
result := con('T'+'', toRope(gUnique))
|
result := con('T'+'', toRope(gUnique))
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function isCArray(typ: PType): bool;
|
function ccgIntroducedPtr(s: PSym): bool;
|
||||||
var
|
|
||||||
t: PType;
|
|
||||||
begin
|
|
||||||
t := skipVarGeneric(typ);
|
|
||||||
case t.kind of
|
|
||||||
tyArray, tyArrayConstr, tyOpenArray: result := true;
|
|
||||||
tySet: result := getSize(t) > 8;
|
|
||||||
else result := false
|
|
||||||
end
|
|
||||||
end;
|
|
||||||
|
|
||||||
function UsePtrPassing(param: PSym): bool;
|
|
||||||
// this is pretty complicated ...
|
|
||||||
var
|
var
|
||||||
pt: PType;
|
pt: PType;
|
||||||
begin
|
begin
|
||||||
pt := param.typ;
|
pt := s.typ;
|
||||||
if (sfResult in param.flags) and not isInvalidReturnType(pt) then
|
assert(not (sfResult in s.flags));
|
||||||
result := false // BUGFIX
|
case pt.Kind of
|
||||||
else if pt.Kind = tyObject then begin
|
tyObject: begin
|
||||||
// objects are always passed by reference,
|
if (optByRef in s.options) or (getSize(pt) > platform.floatSize) then
|
||||||
// otherwise implicit casting doesn't work
|
result := true // requested anyway
|
||||||
result := true;
|
else if (tfFinal in pt.flags) and (pt.sons[0] = nil) then
|
||||||
end
|
result := false // no need, because no subtyping possible
|
||||||
else if (pt.kind in [tyRecordConstr, tyRecord]) and
|
else
|
||||||
((getSize(pt) > platform.floatSize) or
|
result := true; // ordinary objects are always passed by reference,
|
||||||
(optByRef in param.options)) then begin
|
// otherwise casting doesn't work
|
||||||
result := true;
|
end;
|
||||||
end
|
tyTuple:
|
||||||
else if isCArray(pt) then
|
result := (getSize(pt) > platform.floatSize) or (optByRef in s.options);
|
||||||
result := false
|
|
||||||
else if (pt.kind = tyVar) or (getSize(pt) > platform.floatSize) then begin
|
|
||||||
result := true;
|
|
||||||
end
|
|
||||||
else
|
else
|
||||||
result := false
|
result := false
|
||||||
|
end
|
||||||
end;
|
end;
|
||||||
|
|
||||||
const
|
|
||||||
PointerTypes = {@set}[tySequence, tyString, tyRef, tyPtr, tyPointer];
|
|
||||||
|
|
||||||
procedure fillResult(param: PSym);
|
procedure fillResult(param: PSym);
|
||||||
begin
|
begin
|
||||||
fillLoc(param.loc, locParam, param.typ,
|
fillLoc(param.loc, locParam, param.typ, toRope('Result'), OnStack);
|
||||||
toRope('Result'), {@set}[lfOnUnknown]);
|
if (mapType(param.typ) <> ctArray) and IsInvalidReturnType(param.typ) then
|
||||||
if UsePtrPassing(param) then param.loc.indirect := 1
|
begin
|
||||||
|
include(param.loc.flags, lfIndirect);
|
||||||
|
param.loc.s := OnUnknown
|
||||||
|
end
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure genProcParams(t: PType; out rettype, params: PRope);
|
procedure genProcParams(m: BModule; t: PType; out rettype, params: PRope);
|
||||||
var
|
var
|
||||||
i, j: int;
|
i, j: int;
|
||||||
param: PSym;
|
param: PSym;
|
||||||
|
|
@ -165,31 +177,25 @@ begin
|
||||||
// C cannot return arrays (what a poor language...)
|
// C cannot return arrays (what a poor language...)
|
||||||
rettype := toRope('void')
|
rettype := toRope('void')
|
||||||
else
|
else
|
||||||
rettype := getTypeDesc(t.sons[0]);
|
rettype := getTypeDesc(m, t.sons[0]);
|
||||||
for i := 1 to sonsLen(t.n)-1 do begin
|
for i := 1 to sonsLen(t.n)-1 do begin
|
||||||
assert(t.n.sons[i].kind = nkSym);
|
if t.n.sons[i].kind <> nkSym then InternalError(t.n.info, 'genProcParams');
|
||||||
param := t.n.sons[i].sym;
|
param := t.n.sons[i].sym;
|
||||||
fillLoc(param.loc, locParam, param.typ,
|
fillLoc(param.loc, locParam, param.typ, mangleName(param), OnStack);
|
||||||
con(toRope('Par'), toRope(i)), {@set}[lfOnStack]);
|
app(params, getTypeDesc(m, param.typ));
|
||||||
if param.typ.kind = tyVar then begin
|
if ccgIntroducedPtr(param) then begin
|
||||||
param.loc.flags := {@set}[lfOnUnknown]; // BUGFIX!
|
|
||||||
app(params, getTypeDesc(param.typ.sons[0]));
|
|
||||||
end
|
|
||||||
else
|
|
||||||
app(params, getTypeDesc(param.typ));
|
|
||||||
if UsePtrPassing(param) then begin
|
|
||||||
app(params, '*'+'');
|
app(params, '*'+'');
|
||||||
param.loc.indirect := 1
|
include(param.loc.flags, lfIndirect);
|
||||||
|
param.loc.s := OnUnknown;
|
||||||
end;
|
end;
|
||||||
app(params, ' '+'');
|
app(params, ' '+'');
|
||||||
|
|
||||||
app(params, param.loc.r);
|
app(params, param.loc.r);
|
||||||
// declare the len field for open arrays:
|
// declare the len field for open arrays:
|
||||||
arr := param.typ;
|
arr := param.typ;
|
||||||
if arr.kind = tyVar then arr := arr.sons[0];
|
if arr.kind = tyVar then arr := arr.sons[0];
|
||||||
j := 0;
|
j := 0;
|
||||||
while arr.Kind = tyOpenArray do begin // need to pass hidden parameter:
|
while arr.Kind = tyOpenArray do begin // need to pass hidden parameter:
|
||||||
appRopeFormat(params, ', const int $1Len$2', [param.loc.r, toRope(j)]);
|
appf(params, ', NI $1Len$2', [param.loc.r, toRope(j)]);
|
||||||
inc(j);
|
inc(j);
|
||||||
arr := arr.sons[0]
|
arr := arr.sons[0]
|
||||||
end;
|
end;
|
||||||
|
|
@ -197,8 +203,8 @@ begin
|
||||||
end;
|
end;
|
||||||
if (t.sons[0] <> nil) and isInvalidReturnType(t.sons[0]) then begin
|
if (t.sons[0] <> nil) and isInvalidReturnType(t.sons[0]) then begin
|
||||||
if params <> nil then app(params, ', ');
|
if params <> nil then app(params, ', ');
|
||||||
app(params, getTypeDesc(t.sons[0]));
|
app(params, getTypeDesc(m, t.sons[0]));
|
||||||
if not isCArray(t.sons[0]) then app(params, '*'+'');
|
if mapType(t.sons[0]) <> ctArray then app(params, '*'+'');
|
||||||
app(params, ' Result');
|
app(params, ' Result');
|
||||||
end;
|
end;
|
||||||
if t.callConv = ccClosure then begin
|
if t.callConv = ccClosure then begin
|
||||||
|
|
@ -216,11 +222,6 @@ begin
|
||||||
params := con('('+'', params);
|
params := con('('+'', params);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function getLengthOfSet(s: PNode): int;
|
|
||||||
begin
|
|
||||||
result := int(getSize(s.typ))
|
|
||||||
end;
|
|
||||||
|
|
||||||
function isImportedType(t: PType): bool;
|
function isImportedType(t: PType): bool;
|
||||||
begin
|
begin
|
||||||
result := (t.sym <> nil) and (sfImportc in t.sym.flags)
|
result := (t.sym <> nil) and (sfImportc in t.sym.flags)
|
||||||
|
|
@ -228,25 +229,10 @@ end;
|
||||||
|
|
||||||
function getTypeName(typ: PType): PRope;
|
function getTypeName(typ: PType): PRope;
|
||||||
begin
|
begin
|
||||||
if typ.sym <> nil then begin
|
if (typ.sym <> nil) and ([sfImportc, sfExportc] * typ.sym.flags <> []) then
|
||||||
result := typ.sym.loc.r;
|
result := typ.sym.loc.r
|
||||||
if result = nil then begin
|
|
||||||
assert(typ.owner <> nil);
|
|
||||||
result := toRope(mangle(typ.owner.Name.s) + '_' +{&}
|
|
||||||
mangle(typ.sym.name.s));
|
|
||||||
end
|
|
||||||
end
|
|
||||||
else begin
|
else begin
|
||||||
// we must use a unique type id here because we don't store
|
if typ.loc.r = nil then typ.loc.r := con('Ty', toRope(typ.id));
|
||||||
// whether a type has to be given a certain name because its
|
|
||||||
// forward declaration has already been given:
|
|
||||||
if typ.loc.r = nil then begin
|
|
||||||
inc(currMod.unique);
|
|
||||||
assert(typ.owner <> nil);
|
|
||||||
typ.loc.r := ropeFormat('$1_Ty$2', [
|
|
||||||
toRope(mangle(typ.owner.Name.s)),
|
|
||||||
toRope(currMod.unique)])
|
|
||||||
end;
|
|
||||||
result := typ.loc.r
|
result := typ.loc.r
|
||||||
end
|
end
|
||||||
end;
|
end;
|
||||||
|
|
@ -262,18 +248,18 @@ end;
|
||||||
function getSimpleTypeDesc(typ: PType): PRope;
|
function getSimpleTypeDesc(typ: PType): PRope;
|
||||||
const
|
const
|
||||||
NumericalTypeToStr: array [tyInt..tyFloat128] of string = (
|
NumericalTypeToStr: array [tyInt..tyFloat128] of string = (
|
||||||
'NS', 'NS8', 'NS16', 'NS32', 'NS64', 'NF', 'NF32', 'NF64', 'NF128');
|
'NI', 'NI8', 'NI16', 'NI32', 'NI64', 'NF', 'NF32', 'NF64', 'NF128');
|
||||||
begin
|
begin
|
||||||
case typ.Kind of
|
case typ.Kind of
|
||||||
tyPointer: result := typeNameOrLiteral(typ, 'void*');
|
tyPointer: result := typeNameOrLiteral(typ, 'void*');
|
||||||
tyEnum: begin
|
tyEnum: begin
|
||||||
if firstOrd(typ) < 0 then
|
if firstOrd(typ) < 0 then
|
||||||
result := typeNameOrLiteral(typ, 'NS32')
|
result := typeNameOrLiteral(typ, 'NI32')
|
||||||
else begin
|
else begin
|
||||||
case int(getSize(typ)) of
|
case int(getSize(typ)) of
|
||||||
1: result := typeNameOrLiteral(typ, 'NU8');
|
1: result := typeNameOrLiteral(typ, 'NU8');
|
||||||
2: result := typeNameOrLiteral(typ, 'NU16');
|
2: result := typeNameOrLiteral(typ, 'NU16');
|
||||||
4: result := typeNameOrLiteral(typ, 'NS32');
|
4: result := typeNameOrLiteral(typ, 'NI32');
|
||||||
else begin
|
else begin
|
||||||
internalError('getSimpleTypeDesc()');
|
internalError('getSimpleTypeDesc()');
|
||||||
result := nil
|
result := nil
|
||||||
|
|
@ -293,14 +279,14 @@ begin
|
||||||
end
|
end
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function getTypePre(typ: PType): PRope;
|
function getTypePre(m: BModule; typ: PType): PRope;
|
||||||
begin
|
begin
|
||||||
if typ = nil then
|
if typ = nil then
|
||||||
result := toRope('void')
|
result := toRope('void')
|
||||||
else begin
|
else begin
|
||||||
result := getSimpleTypeDesc(typ);
|
result := getSimpleTypeDesc(typ);
|
||||||
if result = nil then
|
if result = nil then
|
||||||
result := CacheGetType(currMod.typeCache, typ)
|
result := CacheGetType(m.typeCache, typ)
|
||||||
end
|
end
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
@ -310,19 +296,18 @@ begin
|
||||||
else result := 'typedef struct $1 $1;$n'
|
else result := 'typedef struct $1 $1;$n'
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function getTypeForward(typ: PType): PRope;
|
function getTypeForward(m: BModule; typ: PType): PRope;
|
||||||
begin
|
begin
|
||||||
result := CacheGetType(currMod.forwTypeCache, typ);
|
result := CacheGetType(m.forwTypeCache, typ);
|
||||||
if result <> nil then exit;
|
if result <> nil then exit;
|
||||||
result := getTypePre(typ);
|
result := getTypePre(m, typ);
|
||||||
if result <> nil then exit;
|
if result <> nil then exit;
|
||||||
case typ.kind of
|
case typ.kind of
|
||||||
tySequence, tyRecord, tyObject: begin
|
tySequence, tyTuple, tyObject: begin
|
||||||
result := getTypeName(typ);
|
result := getTypeName(typ);
|
||||||
if not isImportedType(typ) then
|
if not isImportedType(typ) then
|
||||||
appRopeFormat(currMod.s[cfsForwardTypes],
|
appf(m.s[cfsForwardTypes], getForwardStructFormat(), [result]);
|
||||||
getForwardStructFormat(), [result]);
|
IdTablePut(m.forwTypeCache, typ, result)
|
||||||
IdTablePut(currMod.forwTypeCache, typ, result)
|
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
InternalError('getTypeForward(' + typeKindToStr[typ.kind] + ')')
|
InternalError('getTypeForward(' + typeKindToStr[typ.kind] + ')')
|
||||||
|
|
@ -333,205 +318,254 @@ function mangleRecFieldName(field: PSym; rectype: PType): PRope;
|
||||||
begin
|
begin
|
||||||
if (rectype.sym <> nil)
|
if (rectype.sym <> nil)
|
||||||
and ([sfImportc, sfExportc] * rectype.sym.flags <> []) then
|
and ([sfImportc, sfExportc] * rectype.sym.flags <> []) then
|
||||||
result := toRope(field.name.s)
|
result := field.loc.r
|
||||||
else
|
else
|
||||||
result := toRope(mangle(field.name.s))
|
result := toRope(mangle(field.name.s));
|
||||||
|
if result = nil then InternalError(field.info, 'mangleRecFieldName');
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function genRecordFieldsAux(n: PNode; accessExpr: PRope; rectype: PType): PRope;
|
function genRecordFieldsAux(m: BModule; n: PNode; accessExpr: PRope;
|
||||||
|
rectype: PType): PRope;
|
||||||
var
|
var
|
||||||
i: int;
|
i: int;
|
||||||
ae, uname, sname, a: PRope;
|
ae, uname, sname, a: PRope;
|
||||||
m: PNode;
|
k: PNode;
|
||||||
field: PSym;
|
field: PSym;
|
||||||
begin
|
begin
|
||||||
result := nil;
|
result := nil;
|
||||||
case n.kind of
|
case n.kind of
|
||||||
nkRecList: begin
|
nkRecList: begin
|
||||||
for i := 0 to sonsLen(n)-1 do begin
|
for i := 0 to sonsLen(n)-1 do begin
|
||||||
app(result, genRecordFieldsAux(n.sons[i], accessExpr, rectype));
|
app(result, genRecordFieldsAux(m, n.sons[i], accessExpr, rectype));
|
||||||
end
|
end
|
||||||
end;
|
end;
|
||||||
nkRecCase: begin
|
nkRecCase: begin
|
||||||
assert(n.sons[0].kind = nkSym);
|
if (n.sons[0].kind <> nkSym) then
|
||||||
app(result, genRecordFieldsAux(n.sons[0], accessExpr, rectype));
|
InternalError(n.info, 'genRecordFieldsAux');
|
||||||
|
app(result, genRecordFieldsAux(m, n.sons[0], accessExpr, rectype));
|
||||||
uname := toRope(mangle(n.sons[0].sym.name.s)+ 'U');
|
uname := toRope(mangle(n.sons[0].sym.name.s)+ 'U');
|
||||||
if accessExpr <> nil then ae := ropeFormat('$1.$2', [accessExpr, uname])
|
if accessExpr <> nil then ae := ropef('$1.$2', [accessExpr, uname])
|
||||||
else ae := uname;
|
else ae := uname;
|
||||||
app(result, 'union {'+tnl);
|
app(result, 'union {'+tnl);
|
||||||
for i := 1 to sonsLen(n)-1 do begin
|
for i := 1 to sonsLen(n)-1 do begin
|
||||||
case n.sons[i].kind of
|
case n.sons[i].kind of
|
||||||
nkOfBranch, nkElse: begin
|
nkOfBranch, nkElse: begin
|
||||||
m := lastSon(n.sons[i]);
|
k := lastSon(n.sons[i]);
|
||||||
if m.kind <> nkSym then begin
|
if k.kind <> nkSym then begin
|
||||||
sname := con('S'+'', toRope(i));
|
sname := con('S'+'', toRope(i));
|
||||||
a := genRecordFieldsAux(m, ropeFormat('$1.$2', [ae, sname]),
|
a := genRecordFieldsAux(m, k, ropef('$1.$2', [ae, sname]),
|
||||||
rectype);
|
rectype);
|
||||||
if a <> nil then begin
|
if a <> nil then begin
|
||||||
app(result, 'struct {');
|
app(result, 'struct {');
|
||||||
app(result, a);
|
app(result, a);
|
||||||
appRopeFormat(result, '} $1;$n', [sname]);
|
appf(result, '} $1;$n', [sname]);
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
else app(result, genRecordFieldsAux(m, ae, rectype));
|
else app(result, genRecordFieldsAux(m, k, ae, rectype));
|
||||||
end;
|
end;
|
||||||
else internalError('genRecordFieldsAux(record case branch)');
|
else internalError('genRecordFieldsAux(record case branch)');
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
appRopeFormat(result, '} $1;$n', [uname])
|
appf(result, '} $1;$n', [uname])
|
||||||
end;
|
end;
|
||||||
nkSym: begin
|
nkSym: begin
|
||||||
field := n.sym;
|
field := n.sym;
|
||||||
assert(field.ast = nil);
|
assert(field.ast = nil);
|
||||||
sname := mangleRecFieldName(field, rectype);
|
sname := mangleRecFieldName(field, rectype);
|
||||||
if accessExpr <> nil then ae := ropeFormat('$1.$2', [accessExpr, sname])
|
if accessExpr <> nil then ae := ropef('$1.$2', [accessExpr, sname])
|
||||||
else ae := sname;
|
else ae := sname;
|
||||||
fillLoc(field.loc, locField, field.typ, ae, {@set}[]);
|
fillLoc(field.loc, locField, field.typ, ae, OnUnknown);
|
||||||
appRopeFormat(result, '$1 $2;$n', [getTypeDesc(field.loc.t), sname])
|
appf(result, '$1 $2;$n', [getTypeDesc(m, field.loc.t), sname])
|
||||||
end;
|
end;
|
||||||
else internalError(n.info, 'genRecordFieldsAux()');
|
else internalError(n.info, 'genRecordFieldsAux()');
|
||||||
end
|
end
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function getRecordFields(typ: PType): PRope;
|
function getRecordFields(m: BModule; typ: PType): PRope;
|
||||||
begin
|
begin
|
||||||
result := genRecordFieldsAux(typ.n, nil, typ);
|
result := genRecordFieldsAux(m, typ.n, nil, typ);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function getRecordDesc(typ: PType; name: PRope): PRope;
|
function getRecordDesc(m: BModule; typ: PType; name: PRope): PRope;
|
||||||
var
|
var
|
||||||
desc: PRope;
|
desc: PRope;
|
||||||
|
hasField: bool;
|
||||||
begin
|
begin
|
||||||
// declare the record:
|
// declare the record:
|
||||||
|
hasField := false;
|
||||||
if typ.kind = tyObject then begin
|
if typ.kind = tyObject then begin
|
||||||
useMagic('TNimType');
|
useMagic(m, 'TNimType');
|
||||||
if typ.sons[0] = nil then begin
|
if typ.sons[0] = nil then begin
|
||||||
if (typ.sym <> nil) and (sfPure in typ.sym.flags) then
|
if (typ.sym <> nil) and (sfPure in typ.sym.flags)
|
||||||
result := ropeFormat('struct $1 {$n', [name])
|
or (tfFinal in typ.flags) then
|
||||||
else
|
result := ropef('struct $1 {$n', [name])
|
||||||
result := ropeFormat('struct $1 {$nTNimType* m_type;$n', [name])
|
else begin
|
||||||
|
result := ropef('struct $1 {$nTNimType* m_type;$n', [name]);
|
||||||
|
hasField := true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else if gCmd = cmdCompileToCpp then begin
|
||||||
|
result := ropef('struct $1 : public $2 {$n',
|
||||||
|
[name, getTypeDesc(m, typ.sons[0])]);
|
||||||
|
hasField := true
|
||||||
|
end
|
||||||
|
else begin
|
||||||
|
result := ropef('struct $1 {$n $2 Sup;$n',
|
||||||
|
[name, getTypeDesc(m, typ.sons[0])]);
|
||||||
|
hasField := true
|
||||||
end
|
end
|
||||||
else if gCmd = cmdCompileToCpp then
|
|
||||||
result := ropeFormat('struct $1 : public $2 {$n',
|
|
||||||
[name, getTypeDesc(typ.sons[0])])
|
|
||||||
else
|
|
||||||
result := ropeFormat('struct $1 {$n $2 Sup;$n',
|
|
||||||
[name, getTypeDesc(typ.sons[0])])
|
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
result := ropeFormat('struct $1 {$n', [name]);
|
result := ropef('struct $1 {$n', [name]);
|
||||||
desc := getRecordFields(typ);
|
desc := getRecordFields(m, typ);
|
||||||
if (typ.kind <> tyObject) and (desc = nil) and (gCmd <> cmdCompileToCpp) then
|
if (desc = nil) and not hasField then
|
||||||
// no fields in struct are not valid in C, so generate a dummy:
|
// no fields in struct are not valid in C, so generate a dummy:
|
||||||
appRopeFormat(result, 'char dummy;$n', [])
|
appf(result, 'char dummy;$n', [])
|
||||||
else
|
else
|
||||||
app(result, desc);
|
app(result, desc);
|
||||||
app(result, '};' + tnl);
|
app(result, '};' + tnl);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function getTypeDesc(typ: PType): PRope;
|
procedure pushType(m: BModule; typ: PType);
|
||||||
|
var
|
||||||
|
L: int;
|
||||||
|
begin
|
||||||
|
L := length(m.typeStack);
|
||||||
|
setLength(m.typeStack, L+1);
|
||||||
|
m.typeStack[L] := typ;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function getTypeDesc(m: BModule; typ: PType): PRope;
|
||||||
// returns only the type's name
|
// returns only the type's name
|
||||||
var
|
var
|
||||||
name, rettype, desc, recdesc: PRope;
|
name, rettype, desc, recdesc: PRope;
|
||||||
n: biggestInt;
|
n: biggestInt;
|
||||||
|
t, et: PType;
|
||||||
begin
|
begin
|
||||||
if typ.sym <> nil then useHeader(typ.sym);
|
t := getUniqueType(typ);
|
||||||
result := getTypePre(typ);
|
if t = nil then InternalError('getTypeDesc: t == nil');
|
||||||
|
if t.sym <> nil then useHeader(m, t.sym);
|
||||||
|
result := getTypePre(m, t);
|
||||||
if result <> nil then exit;
|
if result <> nil then exit;
|
||||||
case typ.Kind of
|
case t.Kind of
|
||||||
tyRef, tyPtr, tyVar, tyOpenArray: begin
|
tyRef, tyPtr, tyVar, tyOpenArray: begin
|
||||||
case typ.sons[0].Kind of
|
et := getUniqueType(t.sons[0]);
|
||||||
tyRecord, tyObject, tySequence: begin
|
if et.kind in [tyArrayConstr, tyArray, tyOpenArray] then
|
||||||
// no restriction!
|
et := getUniqueType(elemType(et));
|
||||||
// We have a forward declaration for structs
|
case et.Kind of
|
||||||
name := getTypeForward(typ.sons[0]);
|
tyObject, tyTuple: begin
|
||||||
|
// no restriction! We have a forward declaration for structs
|
||||||
|
name := getTypeForward(m, et);
|
||||||
result := con(name, '*'+'');
|
result := con(name, '*'+'');
|
||||||
IdTablePut(currMod.typeCache, typ, result)
|
IdTablePut(m.typeCache, t, result);
|
||||||
|
pushType(m, et);
|
||||||
|
end;
|
||||||
|
tySequence: begin
|
||||||
|
// no restriction! We have a forward declaration for structs
|
||||||
|
name := getTypeForward(m, et);
|
||||||
|
result := con(name, '**');
|
||||||
|
IdTablePut(m.typeCache, t, result);
|
||||||
|
pushType(m, et);
|
||||||
end;
|
end;
|
||||||
else begin
|
else begin
|
||||||
// else we have a strong dependency :-(
|
// else we have a strong dependency :-(
|
||||||
result := con(getTypeDesc(typ.sons[0]), '*'+'');
|
result := con(getTypeDesc(m, et), '*'+'');
|
||||||
IdTablePut(currMod.typeCache, typ, result)
|
IdTablePut(m.typeCache, t, result)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end;
|
end;
|
||||||
tyProc: begin
|
tyProc: begin
|
||||||
result := getTypeName(typ);
|
result := getTypeName(t);
|
||||||
IdTablePut(currMod.typeCache, typ, result);
|
IdTablePut(m.typeCache, t, result);
|
||||||
genProcParams(typ, rettype, desc);
|
genProcParams(m, t, rettype, desc);
|
||||||
if not isImportedType(typ) then begin
|
if not isImportedType(t) then begin
|
||||||
if typ.callConv <> ccClosure then
|
if t.callConv <> ccClosure then
|
||||||
appRopeFormat(currMod.s[cfsTypes], 'typedef $1_PTR($2, $3) $4;$n',
|
appf(m.s[cfsTypes], 'typedef $1_PTR($2, $3) $4;$n',
|
||||||
[toRope(CallingConvToStr[typ.callConv]), rettype, result, desc])
|
[toRope(CallingConvToStr[t.callConv]), rettype, result, desc])
|
||||||
else // procedure vars may need a closure!
|
else // procedure vars may need a closure!
|
||||||
appRopeFormat(currMod.s[cfsTypes], 'typedef struct $1 {$n' +
|
appf(m.s[cfsTypes], 'typedef struct $1 {$n' +
|
||||||
'N_CDECL_PTR($2, PrcPart) $3;$n' +
|
'N_CDECL_PTR($2, PrcPart) $3;$n' +
|
||||||
'void* ClPart;$n};$n',
|
'void* ClPart;$n};$n',
|
||||||
[result, rettype, desc]);
|
[result, rettype, desc]);
|
||||||
end
|
end
|
||||||
end;
|
end;
|
||||||
tySequence: begin
|
tySequence: begin
|
||||||
// we cannot use getTypeForward here because then typ would be associated
|
// we cannot use getTypeForward here because then t would be associated
|
||||||
// with the name of the struct, not with the pointer to the struct:
|
// with the name of the struct, not with the pointer to the struct:
|
||||||
result := getTypeName(typ);
|
result := CacheGetType(m.forwTypeCache, t);
|
||||||
IdTablePut(currMod.typeCache, typ, con(result, '*'+''));
|
if result = nil then begin
|
||||||
if not isImportedType(typ) then begin
|
result := getTypeName(t);
|
||||||
appRopeFormat(currMod.s[cfsForwardTypes],
|
if not isImportedType(t) then
|
||||||
getForwardStructFormat(), [result]);
|
appf(m.s[cfsForwardTypes], getForwardStructFormat(), [result]);
|
||||||
appRopeFormat(currMod.s[cfsSeqTypes],
|
IdTablePut(m.forwTypeCache, t, result);
|
||||||
// BUGFIX: needed to introduce cfsSeqTypes
|
|
||||||
'struct $2 {$n' +
|
|
||||||
' NS len, space;$n' +
|
|
||||||
' $1 data[SEQ_DECL_SIZE];$n' +
|
|
||||||
'};$n', [getTypeDesc(typ.sons[0]), result]);
|
|
||||||
end;
|
end;
|
||||||
|
assert(CacheGetType(m.typeCache, t) = nil);
|
||||||
|
IdTablePut(m.typeCache, t, con(result, '*'+''));
|
||||||
|
if not isImportedType(t) then
|
||||||
|
appf(m.s[cfsSeqTypes],
|
||||||
|
'struct $2 {$n' +
|
||||||
|
' NI len, space;$n' +
|
||||||
|
' $1 data[SEQ_DECL_SIZE];$n' +
|
||||||
|
'};$n', [getTypeDesc(m, t.sons[0]), result]);
|
||||||
app(result, '*'+'');
|
app(result, '*'+'');
|
||||||
end;
|
end;
|
||||||
tyArrayConstr, tyArray: begin
|
tyArrayConstr, tyArray: begin
|
||||||
n := lengthOrd(typ);
|
n := lengthOrd(t);
|
||||||
if n <= 0 then n := 1; // make an array of at least one element
|
if n <= 0 then n := 1; // make an array of at least one element
|
||||||
result := getTypeName(typ);
|
result := getTypeName(t);
|
||||||
IdTablePut(currMod.typeCache, typ, result);
|
IdTablePut(m.typeCache, t, result);
|
||||||
if not isImportedType(typ) then
|
if not isImportedType(t) then
|
||||||
appRopeFormat(currMod.s[cfsTypes], 'typedef $1 $2[$3];$n',
|
appf(m.s[cfsTypes], 'typedef $1 $2[$3];$n',
|
||||||
[getTypeDesc(typ.sons[1]), result, ToRope(n)])
|
[getTypeDesc(m, t.sons[1]), result, ToRope(n)])
|
||||||
end;
|
end;
|
||||||
tyObject, tyRecord, tyRecordConstr: begin
|
tyObject, tyTuple: begin
|
||||||
result := getTypeName(typ);
|
result := CacheGetType(m.forwTypeCache, t);
|
||||||
IdTablePut(currMod.typeCache, typ, result);
|
if result = nil then begin
|
||||||
recdesc := getRecordDesc(typ, result); // always compute for sideeffects
|
result := getTypeName(t);
|
||||||
if not isImportedType(typ) then
|
if not isImportedType(t) then
|
||||||
app(currMod.s[cfsTypes], recdesc);
|
appf(m.s[cfsForwardTypes],
|
||||||
if CacheGetType(currMod.forwTypeCache, typ) = nil then begin
|
|
||||||
if not isImportedType(typ) then
|
|
||||||
appRopeFormat(currMod.s[cfsForwardTypes],
|
|
||||||
getForwardStructFormat(), [result]);
|
getForwardStructFormat(), [result]);
|
||||||
IdTablePut(currMod.forwTypeCache, typ, result)
|
IdTablePut(m.forwTypeCache, t, result)
|
||||||
end
|
end;
|
||||||
|
IdTablePut(m.typeCache, t, result);
|
||||||
|
recdesc := getRecordDesc(m, t, result); // always call for sideeffects
|
||||||
|
if not isImportedType(t) then app(m.s[cfsTypes], recdesc);
|
||||||
end;
|
end;
|
||||||
tySet: begin
|
tySet: begin
|
||||||
case int(getSize(typ)) of
|
case int(getSize(t)) of
|
||||||
1: result := toRope('NS8');
|
1: result := toRope('NU8');
|
||||||
2: result := toRope('NS16');
|
2: result := toRope('NU16');
|
||||||
4: result := toRope('NS32');
|
4: result := toRope('NU32');
|
||||||
8: result := toRope('NS64');
|
8: result := toRope('NU64');
|
||||||
else begin
|
else begin
|
||||||
result := getTypeName(typ);
|
result := getTypeName(t);
|
||||||
IdTablePut(currMod.typeCache, typ, result);
|
IdTablePut(m.typeCache, t, result);
|
||||||
if not isImportedType(typ) then
|
if not isImportedType(t) then
|
||||||
appRopeFormat(currMod.s[cfsTypes], 'typedef NS8 $1[$2];$n',
|
appf(m.s[cfsTypes], 'typedef NU8 $1[$2];$n',
|
||||||
[result, toRope(getSize(typ))])
|
[result, toRope(getSize(t))])
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
end;
|
||||||
|
tyGenericInst: result := getTypeDesc(m, lastSon(t));
|
||||||
else begin
|
else begin
|
||||||
InternalError('getTypeDesc(' + typeKindToStr[typ.kind] + ')');
|
InternalError('getTypeDesc(' + typeKindToStr[t.kind] + ')');
|
||||||
result := nil
|
result := nil
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function genProcHeader(prc: PSym): PRope;
|
procedure finishTypeDescriptions(m: BModule);
|
||||||
|
var
|
||||||
|
i: int;
|
||||||
|
begin
|
||||||
|
i := 0;
|
||||||
|
while i < length(m.typeStack) do begin
|
||||||
|
{@discard} getTypeDesc(m, m.typeStack[i]);
|
||||||
|
inc(i);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function genProcHeader(m: BModule; prc: PSym): PRope;
|
||||||
var
|
var
|
||||||
rettype, params: PRope;
|
rettype, params: PRope;
|
||||||
begin
|
begin
|
||||||
|
|
@ -540,9 +574,9 @@ begin
|
||||||
result := toRope('static ')
|
result := toRope('static ')
|
||||||
else
|
else
|
||||||
result := nil;
|
result := nil;
|
||||||
fillLoc(prc.loc, locProc, prc.typ, mangleName(prc), {@set}[]);
|
fillLoc(prc.loc, locProc, prc.typ, mangleName(prc), OnUnknown);
|
||||||
genProcParams(prc.typ, rettype, params);
|
genProcParams(m, prc.typ, rettype, params);
|
||||||
appRopeFormat(result, '$1($2, $3)$4',
|
appf(result, '$1($2, $3)$4',
|
||||||
[toRope(CallingConvToStr[prc.typ.callConv]),
|
[toRope(CallingConvToStr[prc.typ.callConv]),
|
||||||
rettype, prc.loc.r, params])
|
rettype, prc.loc.r, params])
|
||||||
end;
|
end;
|
||||||
|
|
@ -559,19 +593,26 @@ var
|
||||||
tmp: PRope;
|
tmp: PRope;
|
||||||
begin
|
begin
|
||||||
tmp := getTempName();
|
tmp := getTempName();
|
||||||
appRopeFormat(m.s[cfsTypeInit1], 'static TNimType $1;$n', [tmp]);
|
appf(m.s[cfsTypeInit1], 'static TNimType $1;$n', [tmp]);
|
||||||
appRopeFormat(m.s[cfsTypeInit2], '$2 = &$1;$n', [tmp, name]);
|
appf(m.s[cfsTypeInit2], '$2 = &$1;$n', [tmp, name]);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure genTypeInfoAuxBase(m: BModule; typ: PType; name, base: PRope);
|
procedure genTypeInfoAuxBase(m: BModule; typ: PType; name, base: PRope);
|
||||||
|
var
|
||||||
|
nimtypeKind: int;
|
||||||
begin
|
begin
|
||||||
allocMemTI(m, name);
|
allocMemTI(m, name);
|
||||||
appRopeFormat(m.s[cfsTypeInit3],
|
if (typ.kind = tyObject) and (tfFinal in typ.flags)
|
||||||
|
and (typ.sons[0] = nil) then
|
||||||
|
nimtypeKind := ord(high(TTypeKind))+1 // tyPureObject
|
||||||
|
else
|
||||||
|
nimtypeKind := ord(typ.kind);
|
||||||
|
appf(m.s[cfsTypeInit3],
|
||||||
'$1->size = sizeof($2);$n' +
|
'$1->size = sizeof($2);$n' +
|
||||||
'$1->kind = $3;$n' +
|
'$1->kind = $3;$n' +
|
||||||
'$1->base = $4;$n', [
|
'$1->base = $4;$n', [
|
||||||
name, getTypeDesc(typ), toRope(ord(typ.kind)), base]);
|
name, getTypeDesc(m, typ), toRope(nimtypeKind), base]);
|
||||||
appRopeFormat(m.s[cfsVars], 'TNimType* $1;$n', [name]);
|
appf(m.s[cfsVars], 'TNimType* $1;$n', [name]);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure genTypeInfoAux(m: BModule; typ: PType; name: PRope);
|
procedure genTypeInfoAux(m: BModule; typ: PType; name: PRope);
|
||||||
|
|
@ -599,21 +640,21 @@ begin
|
||||||
genObjectFields(m, typ, n.sons[0], expr)
|
genObjectFields(m, typ, n.sons[0], expr)
|
||||||
else if len > 0 then begin
|
else if len > 0 then begin
|
||||||
tmp := getTempName();
|
tmp := getTempName();
|
||||||
appRopeFormat(m.s[cfsTypeInit1], 'static TNimNode* $1[$2];$n',
|
appf(m.s[cfsTypeInit1], 'static TNimNode* $1[$2];$n',
|
||||||
[tmp, toRope(len)]);
|
[tmp, toRope(len)]);
|
||||||
for i := 0 to len-1 do begin
|
for i := 0 to len-1 do begin
|
||||||
tmp2 := getTempName();
|
tmp2 := getTempName();
|
||||||
appRopeFormat(m.s[cfsTypeInit1], 'static TNimNode $1;$n', [tmp2]);
|
appf(m.s[cfsTypeInit1], 'static TNimNode $1;$n', [tmp2]);
|
||||||
appRopeFormat(m.s[cfsTypeInit3], '$1[$2] = &$3;$n',
|
appf(m.s[cfsTypeInit3], '$1[$2] = &$3;$n',
|
||||||
[tmp, toRope(i), tmp2]);
|
[tmp, toRope(i), tmp2]);
|
||||||
genObjectFields(m, typ, n.sons[i], tmp2);
|
genObjectFields(m, typ, n.sons[i], tmp2);
|
||||||
end;
|
end;
|
||||||
appRopeFormat(m.s[cfsTypeInit3],
|
appf(m.s[cfsTypeInit3],
|
||||||
'$1.len = $2; $1.kind = 2; $1.sons = &$3;$n', [
|
'$1.len = $2; $1.kind = 2; $1.sons = &$3[0];$n', [
|
||||||
expr, toRope(len), tmp]);
|
expr, toRope(len), tmp]);
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
appRopeFormat(m.s[cfsTypeInit3],
|
appf(m.s[cfsTypeInit3],
|
||||||
'$1.len = $2; $1.kind = 2;$n', [expr, toRope(len)]);
|
'$1.len = $2; $1.kind = 2;$n', [expr, toRope(len)]);
|
||||||
end;
|
end;
|
||||||
nkRecCase: begin
|
nkRecCase: begin
|
||||||
|
|
@ -621,22 +662,22 @@ begin
|
||||||
assert(n.sons[0].kind = nkSym);
|
assert(n.sons[0].kind = nkSym);
|
||||||
field := n.sons[0].sym;
|
field := n.sons[0].sym;
|
||||||
tmp := getTempName();
|
tmp := getTempName();
|
||||||
appRopeFormat(m.s[cfsTypeInit3], '$1.kind = 3;$n' +
|
appf(m.s[cfsTypeInit3], '$1.kind = 3;$n' +
|
||||||
'$1.offset = offsetof($2, $3);$n' +
|
'$1.offset = offsetof($2, $3);$n' +
|
||||||
'$1.typ = $4;$n' +
|
'$1.typ = $4;$n' +
|
||||||
'$1.name = $5;$n' +
|
'$1.name = $5;$n' +
|
||||||
'$1.sons = &$6;$n' +
|
'$1.sons = &$6[0];$n' +
|
||||||
'$1.len = $7;$n',
|
'$1.len = $7;$n',
|
||||||
[expr, getTypeDesc(typ), field.loc.r,
|
[expr, getTypeDesc(m, typ), field.loc.r,
|
||||||
genTypeInfo(m, field.typ),
|
genTypeInfo(m, field.typ),
|
||||||
makeCString(field.name.s), tmp,
|
makeCString(field.name.s), tmp,
|
||||||
toRope(lengthOrd(field.typ))]);
|
toRope(lengthOrd(field.typ))]);
|
||||||
appRopeFormat(m.s[cfsTypeInit1], 'static TNimNode* $1[$2];$n',
|
appf(m.s[cfsTypeInit1], 'static TNimNode* $1[$2];$n',
|
||||||
[tmp, toRope(lengthOrd(field.typ)+1)]);
|
[tmp, toRope(lengthOrd(field.typ)+1)]);
|
||||||
for i := 1 to len-1 do begin
|
for i := 1 to len-1 do begin
|
||||||
b := n.sons[i]; // branch
|
b := n.sons[i]; // branch
|
||||||
tmp2 := getTempName();
|
tmp2 := getTempName();
|
||||||
appRopeFormat(m.s[cfsTypeInit1], 'static TNimNode $1;$n', [tmp2]);
|
appf(m.s[cfsTypeInit1], 'static TNimNode $1;$n', [tmp2]);
|
||||||
genObjectFields(m, typ, lastSon(b), tmp2);
|
genObjectFields(m, typ, lastSon(b), tmp2);
|
||||||
//writeln(output, renderTree(b.sons[j]));
|
//writeln(output, renderTree(b.sons[j]));
|
||||||
case b.kind of
|
case b.kind of
|
||||||
|
|
@ -648,18 +689,18 @@ begin
|
||||||
x := int(getOrdValue(b.sons[j].sons[0]));
|
x := int(getOrdValue(b.sons[j].sons[0]));
|
||||||
y := int(getOrdValue(b.sons[j].sons[1]));
|
y := int(getOrdValue(b.sons[j].sons[1]));
|
||||||
while x <= y do begin
|
while x <= y do begin
|
||||||
appRopeFormat(m.s[cfsTypeInit3], '$1[$2] = &$3;$n',
|
appf(m.s[cfsTypeInit3], '$1[$2] = &$3;$n',
|
||||||
[tmp, toRope(x), tmp2]);
|
[tmp, toRope(x), tmp2]);
|
||||||
inc(x);
|
inc(x);
|
||||||
end;
|
end;
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
appRopeFormat(m.s[cfsTypeInit3], '$1[$2] = &$3;$n',
|
appf(m.s[cfsTypeInit3], '$1[$2] = &$3;$n',
|
||||||
[tmp, toRope(getOrdValue(b.sons[j])), tmp2])
|
[tmp, toRope(getOrdValue(b.sons[j])), tmp2])
|
||||||
end
|
end
|
||||||
end;
|
end;
|
||||||
nkElse: begin
|
nkElse: begin
|
||||||
appRopeFormat(m.s[cfsTypeInit3], '$1[$2] = &$3;$n',
|
appf(m.s[cfsTypeInit3], '$1[$2] = &$3;$n',
|
||||||
[tmp, toRope(lengthOrd(field.typ)), tmp2]);
|
[tmp, toRope(lengthOrd(field.typ)), tmp2]);
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
|
|
@ -669,11 +710,11 @@ begin
|
||||||
end;
|
end;
|
||||||
nkSym: begin
|
nkSym: begin
|
||||||
field := n.sym;
|
field := n.sym;
|
||||||
appRopeFormat(m.s[cfsTypeInit3], '$1.kind = 1;$n' +
|
appf(m.s[cfsTypeInit3], '$1.kind = 1;$n' +
|
||||||
'$1.offset = offsetof($2, $3);$n' +
|
'$1.offset = offsetof($2, $3);$n' +
|
||||||
'$1.typ = $4;$n' +
|
'$1.typ = $4;$n' +
|
||||||
'$1.name = $5;$n',
|
'$1.name = $5;$n',
|
||||||
[expr, getTypeDesc(typ), field.loc.r,
|
[expr, getTypeDesc(m, typ), field.loc.r,
|
||||||
genTypeInfo(m, field.typ),
|
genTypeInfo(m, field.typ),
|
||||||
makeCString(field.name.s)]);
|
makeCString(field.name.s)]);
|
||||||
end;
|
end;
|
||||||
|
|
@ -685,11 +726,12 @@ procedure genObjectInfo(m: BModule; typ: PType; name: PRope);
|
||||||
var
|
var
|
||||||
tmp: PRope;
|
tmp: PRope;
|
||||||
begin
|
begin
|
||||||
genTypeInfoAux(m, typ, name);
|
if typ.kind = tyObject then genTypeInfoAux(m, typ, name)
|
||||||
|
else genTypeInfoAuxBase(m, typ, name, toRope('0'+''));
|
||||||
tmp := getTempName();
|
tmp := getTempName();
|
||||||
appRopeFormat(m.s[cfsTypeInit1], 'static TNimNode $1;$n', [tmp]);
|
appf(m.s[cfsTypeInit1], 'static TNimNode $1;$n', [tmp]);
|
||||||
genObjectFields(m, typ, typ.n, tmp);
|
genObjectFields(m, typ, typ.n, tmp);
|
||||||
appRopeFormat(m.s[cfsTypeInit3], '$1->node = &$2;$n', [name, tmp]);
|
appf(m.s[cfsTypeInit3], '$1->node = &$2;$n', [name, tmp]);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure genEnumInfo(m: BModule; typ: PType; name: PRope);
|
procedure genEnumInfo(m: BModule; typ: PType; name: PRope);
|
||||||
|
|
@ -702,15 +744,15 @@ begin
|
||||||
tmp := getTempName();
|
tmp := getTempName();
|
||||||
tmp2 := getTempName();
|
tmp2 := getTempName();
|
||||||
len := sonsLen(typ.n);
|
len := sonsLen(typ.n);
|
||||||
appRopeFormat(m.s[cfsTypeInit1], 'static TNimNode* $1[$2];$n' +
|
appf(m.s[cfsTypeInit1], 'static TNimNode* $1[$2];$n' +
|
||||||
'static TNimNode $3;$n',
|
'static TNimNode $3;$n',
|
||||||
[tmp, toRope(len), tmp2]);
|
[tmp, toRope(len), tmp2]);
|
||||||
for i := 0 to len-1 do begin
|
for i := 0 to len-1 do begin
|
||||||
assert(typ.n.sons[i].kind = nkSym);
|
assert(typ.n.sons[i].kind = nkSym);
|
||||||
field := typ.n.sons[i].sym;
|
field := typ.n.sons[i].sym;
|
||||||
tmp3 := getTempName();
|
tmp3 := getTempName();
|
||||||
appRopeFormat(m.s[cfsTypeInit1], 'static TNimNode $1;$n', [tmp3]);
|
appf(m.s[cfsTypeInit1], 'static TNimNode $1;$n', [tmp3]);
|
||||||
appRopeFormat(m.s[cfsTypeInit3], '$1[$2] = &$3;$n' +
|
appf(m.s[cfsTypeInit3], '$1[$2] = &$3;$n' +
|
||||||
'$3.kind = 1;$n' +
|
'$3.kind = 1;$n' +
|
||||||
'$3.offset = $4;$n' +
|
'$3.offset = $4;$n' +
|
||||||
'$3.typ = $5;$n' +
|
'$3.typ = $5;$n' +
|
||||||
|
|
@ -719,8 +761,8 @@ begin
|
||||||
toRope(field.position),
|
toRope(field.position),
|
||||||
name, makeCString(field.name.s)]);
|
name, makeCString(field.name.s)]);
|
||||||
end;
|
end;
|
||||||
appRopeFormat(m.s[cfsTypeInit3],
|
appf(m.s[cfsTypeInit3],
|
||||||
'$1.len = $2; $1.kind = 2; $1.sons = &$3;$n$4->node = &$1;$n', [
|
'$1.len = $2; $1.kind = 2; $1.sons = &$3[0];$n$4->node = &$1;$n', [
|
||||||
tmp2, toRope(len), tmp, name]);
|
tmp2, toRope(len), tmp, name]);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
@ -731,8 +773,8 @@ begin
|
||||||
assert(typ.sons[0] <> nil);
|
assert(typ.sons[0] <> nil);
|
||||||
genTypeInfoAux(m, typ, name);
|
genTypeInfoAux(m, typ, name);
|
||||||
tmp := getTempName();
|
tmp := getTempName();
|
||||||
appRopeFormat(m.s[cfsTypeInit1], 'static TNimNode $1;$n', [tmp]);
|
appf(m.s[cfsTypeInit1], 'static TNimNode $1;$n', [tmp]);
|
||||||
appRopeFormat(m.s[cfsTypeInit3],
|
appf(m.s[cfsTypeInit3],
|
||||||
'$1.len = $2; $1.kind = 0;$n' +
|
'$1.len = $2; $1.kind = 0;$n' +
|
||||||
'$3->node = &$1;$n', [tmp, toRope(firstOrd(typ)), name]);
|
'$3->node = &$1;$n', [tmp, toRope(firstOrd(typ)), name]);
|
||||||
end;
|
end;
|
||||||
|
|
@ -746,14 +788,13 @@ function genTypeInfo(m: BModule; typ: PType): PRope;
|
||||||
var
|
var
|
||||||
t: PType;
|
t: PType;
|
||||||
begin
|
begin
|
||||||
t := typ;
|
t := getUniqueType(typ);
|
||||||
if t.kind = tyGenericInst then t := lastSon(t);
|
result := ropef('NTI$1', [toRope(t.id)]);
|
||||||
result := ropeFormat('NTI$1', [toRope(t.id)]);
|
|
||||||
if not IntSetContainsOrIncl(m.typeInfoMarker, t.id) then begin
|
if not IntSetContainsOrIncl(m.typeInfoMarker, t.id) then begin
|
||||||
// declare type information structures:
|
// declare type information structures:
|
||||||
useMagic('TNimType');
|
useMagic(m, 'TNimType');
|
||||||
useMagic('TNimNode');
|
useMagic(m, 'TNimNode');
|
||||||
appRopeFormat(m.s[cfsVars], 'extern TNimType* $1;$n', [result]);
|
appf(m.s[cfsVars], 'extern TNimType* $1;$n', [result]);
|
||||||
end;
|
end;
|
||||||
if IntSetContainsOrIncl(gTypeInfoGenerated, t.id) then exit;
|
if IntSetContainsOrIncl(gTypeInfoGenerated, t.id) then exit;
|
||||||
case t.kind of
|
case t.kind of
|
||||||
|
|
@ -763,7 +804,7 @@ begin
|
||||||
tyArrayConstr, tyArray: genArrayInfo(m, t, result);
|
tyArrayConstr, tyArray: genArrayInfo(m, t, result);
|
||||||
tySet: genSetInfo(m, t, result);
|
tySet: genSetInfo(m, t, result);
|
||||||
tyEnum: genEnumInfo(m, t, result);
|
tyEnum: genEnumInfo(m, t, result);
|
||||||
tyObject, tyRecord, tyRecordConstr: genObjectInfo(m, t, result);
|
tyObject, tyTuple: genObjectInfo(m, t, result);
|
||||||
tyVar: result := genTypeInfo(m, typ.sons[0]);
|
tyVar: result := genTypeInfo(m, typ.sons[0]);
|
||||||
else InternalError('genTypeInfo(' + typekindToStr[t.kind] + ')');
|
else InternalError('genTypeInfo(' + typekindToStr[t.kind] + ')');
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -17,15 +17,41 @@ interface
|
||||||
|
|
||||||
uses
|
uses
|
||||||
charsets, nsystem,
|
charsets, nsystem,
|
||||||
ast, astalgo, ropes, lists, hashes, strutils, types;
|
ast, astalgo, ropes, lists, hashes, strutils, types, msgs;
|
||||||
|
|
||||||
function toCChar(c: Char): string;
|
function toCChar(c: Char): string;
|
||||||
function makeCString(const s: string): PRope;
|
function makeCString(const s: string): PRope;
|
||||||
|
|
||||||
function TableGetType(const tab: TIdTable; key: PType): PObject;
|
function TableGetType(const tab: TIdTable; key: PType): PObject;
|
||||||
|
function GetUniqueType(key: PType): PType;
|
||||||
|
|
||||||
implementation
|
implementation
|
||||||
|
|
||||||
|
var
|
||||||
|
gTypeTable: TIdTable;
|
||||||
|
|
||||||
|
function GetUniqueType(key: PType): PType;
|
||||||
|
var
|
||||||
|
t: PType;
|
||||||
|
h: THash;
|
||||||
|
begin
|
||||||
|
result := key;
|
||||||
|
if key = nil then exit;
|
||||||
|
assert(key.kind <> tyForward);
|
||||||
|
if key.kind = tyGenericInst then begin
|
||||||
|
result := GetUniqueType(lastSon(key));
|
||||||
|
exit
|
||||||
|
end;
|
||||||
|
if IdTableHasObjectAsKey(gTypeTable, key) then exit;
|
||||||
|
// we have to do a slow linear search because types may need
|
||||||
|
// to be compared by their structure:
|
||||||
|
for h := 0 to high(gTypeTable.data) do begin
|
||||||
|
t := PType(gTypeTable.data[h].key);
|
||||||
|
if (t <> nil) and sameType(t, key) then begin result := t; exit end
|
||||||
|
end;
|
||||||
|
IdTablePut(gTypeTable, key, key);
|
||||||
|
end;
|
||||||
|
|
||||||
function TableGetType(const tab: TIdTable; key: PType): PObject;
|
function TableGetType(const tab: TIdTable; key: PType): PObject;
|
||||||
var
|
var
|
||||||
t: PType;
|
t: PType;
|
||||||
|
|
@ -69,7 +95,7 @@ begin
|
||||||
result := nil;
|
result := nil;
|
||||||
res := '"'+'';
|
res := '"'+'';
|
||||||
for i := strStart to length(s)+strStart-1 do begin
|
for i := strStart to length(s)+strStart-1 do begin
|
||||||
if i mod MaxLineLength = 0 then begin
|
if (i-strStart+1) mod MaxLineLength = 0 then begin
|
||||||
res := res +{&} '"' +{&} nl;
|
res := res +{&} '"' +{&} nl;
|
||||||
app(result, toRope(res));
|
app(result, toRope(res));
|
||||||
res := '"'+''; // reset
|
res := '"'+''; // reset
|
||||||
|
|
@ -80,4 +106,6 @@ begin
|
||||||
app(result, toRope(res));
|
app(result, toRope(res));
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
initialization
|
||||||
|
InitIdTable(gTypeTable);
|
||||||
end.
|
end.
|
||||||
|
|
|
||||||
370
nim/cgen.pas
370
nim/cgen.pas
|
|
@ -43,13 +43,28 @@ type
|
||||||
cfsProcHeaders, // section for C procs prototypes
|
cfsProcHeaders, // section for C procs prototypes
|
||||||
cfsProcs, // section for C procs that are not inline
|
cfsProcs, // section for C procs that are not inline
|
||||||
cfsTypeInit1, // section 1 for declarations of type information
|
cfsTypeInit1, // section 1 for declarations of type information
|
||||||
cfsTypeInit2, // section A for initialization of type information
|
cfsTypeInit2, // section 2 for initialization of type information
|
||||||
cfsTypeInit3, // section B for init of type information
|
cfsTypeInit3, // section 3 for init of type information
|
||||||
cfsDebugInit, // section for initialization of debug information
|
cfsDebugInit, // section for initialization of debug information
|
||||||
cfsDynLibInit, // section for initialization of dynamic library binding
|
cfsDynLibInit, // section for initialization of dynamic library binding
|
||||||
cfsDynLibDeinit // section for deinitialization of dynamic libraries
|
cfsDynLibDeinit // section for deinitialization of dynamic libraries
|
||||||
);
|
);
|
||||||
|
|
||||||
|
TCTypeKind = ( // describes the type kind of a C type
|
||||||
|
ctVoid,
|
||||||
|
ctChar,
|
||||||
|
ctBool,
|
||||||
|
ctUInt, ctUInt8, ctUInt16, ctUInt32, ctUInt64,
|
||||||
|
ctInt, ctInt8, ctInt16, ctInt32, ctInt64,
|
||||||
|
ctFloat, ctFloat32, ctFloat64, ctFloat128,
|
||||||
|
ctArray,
|
||||||
|
ctStruct,
|
||||||
|
ctPtr,
|
||||||
|
ctNimStr,
|
||||||
|
ctNimSeq,
|
||||||
|
ctProc,
|
||||||
|
ctCString
|
||||||
|
);
|
||||||
|
|
||||||
TCFileSections = array [TCFileSection] of PRope;
|
TCFileSections = array [TCFileSection] of PRope;
|
||||||
// TCFileSections represents a generated C file
|
// TCFileSections represents a generated C file
|
||||||
|
|
@ -66,15 +81,20 @@ type
|
||||||
BModule = ^TCGen;
|
BModule = ^TCGen;
|
||||||
BProc = ^TCProc;
|
BProc = ^TCProc;
|
||||||
|
|
||||||
|
TBlock = record
|
||||||
|
id: int; // the ID of the label; positive means that it
|
||||||
|
// has been used (i.e. the label should be emitted)
|
||||||
|
nestedTryStmts: int; // how many try statements is it nested into
|
||||||
|
end;
|
||||||
|
|
||||||
TCProc = record // represents C proc that is currently generated
|
TCProc = record // represents C proc that is currently generated
|
||||||
s: TCProcSections; // the procs sections; short name for readability
|
s: TCProcSections; // the procs sections; short name for readability
|
||||||
prc: PSym; // the Nimrod proc that this C proc belongs to
|
prc: PSym; // the Nimrod proc that this C proc belongs to
|
||||||
BeforeRetNeeded: bool; // true iff 'BeforeRet' label for proc is needed
|
BeforeRetNeeded: bool; // true iff 'BeforeRet' label for proc is needed
|
||||||
inTryStmt: Natural; // wether we are in a try statement
|
nestedTryStmts: Natural; // in how many nested try statements we are
|
||||||
// (the vars must be volatile then)
|
// (the vars must be volatile then)
|
||||||
unique: Natural; // for generating unique names in the C proc
|
labels: Natural; // for generating unique labels in the C proc
|
||||||
blocks: array of int; // the ID of the label; positive means that it
|
blocks: array of TBlock; // nested blocks
|
||||||
// has been used (i.e. the label should be emitted)
|
|
||||||
locals: array of TLoc; // locNone means slot is free again
|
locals: array of TLoc; // locNone means slot is free again
|
||||||
options: TOptions; // options that should be used for code
|
options: TOptions; // options that should be used for code
|
||||||
// generation; this is the same as prc.options
|
// generation; this is the same as prc.options
|
||||||
|
|
@ -82,8 +102,9 @@ type
|
||||||
frameLen: int; // current length of frame descriptor
|
frameLen: int; // current length of frame descriptor
|
||||||
sendClosure: PType; // closure record type that we pass
|
sendClosure: PType; // closure record type that we pass
|
||||||
receiveClosure: PType; // closure record type that we get
|
receiveClosure: PType; // closure record type that we get
|
||||||
|
module: BModule; // used to prevent excessive parameter passing
|
||||||
end;
|
end;
|
||||||
|
TTypeSeq = array of PType;
|
||||||
TCGen = object(TBackend) // represents a C source file
|
TCGen = object(TBackend) // represents a C source file
|
||||||
s: TCFileSections; // sections of the C file
|
s: TCFileSections; // sections of the C file
|
||||||
cfilename: string; // filename of the module (including path,
|
cfilename: string; // filename of the module (including path,
|
||||||
|
|
@ -93,55 +114,48 @@ type
|
||||||
declaredThings: TIntSet; // things we have declared in this .c file
|
declaredThings: TIntSet; // things we have declared in this .c file
|
||||||
debugDeclared: TIntSet; // for debugging purposes
|
debugDeclared: TIntSet; // for debugging purposes
|
||||||
headerFiles: TLinkedList; // needed headers to include
|
headerFiles: TLinkedList; // needed headers to include
|
||||||
unique: Natural; // for generating unique names
|
//unique: Natural; // for generating unique names
|
||||||
typeInfoMarker: TIntSet; // needed for generating type information
|
typeInfoMarker: TIntSet; // needed for generating type information
|
||||||
initProc: BProc; // code for init procedure
|
initProc: BProc; // code for init procedure
|
||||||
|
typeStack: TTypeSeq; // used for type generation
|
||||||
end;
|
end;
|
||||||
|
|
||||||
var
|
var
|
||||||
currMod: BModule; // currently compiled module
|
gUnique: Natural;
|
||||||
// a global so that this needs not to be
|
|
||||||
// passed to every proc
|
|
||||||
mainModProcs, mainModInit: PRope; // parts of the main module
|
mainModProcs, mainModInit: PRope; // parts of the main module
|
||||||
gMapping: PRope; // the generated mapping file (if requested)
|
gMapping: PRope; // the generated mapping file (if requested)
|
||||||
|
|
||||||
constTok: PRope; // either 'const ' or nil depending on gCmd
|
function initLoc(k: TLocKind; typ: PType; s: TStorageLoc): TLoc;
|
||||||
|
|
||||||
function initLoc(k: TLocKind; typ: PType): TLoc;
|
|
||||||
begin
|
begin
|
||||||
result.k := k;
|
result.k := k;
|
||||||
result.t := typ;
|
result.s := s;
|
||||||
|
result.t := GetUniqueType(typ);
|
||||||
result.r := nil;
|
result.r := nil;
|
||||||
result.a := -1;
|
result.a := -1;
|
||||||
result.indirect := 0;
|
|
||||||
result.flags := {@set}[]
|
result.flags := {@set}[]
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure fillLoc(var a: TLoc; k: TLocKind; typ: PType; r: PRope;
|
procedure fillLoc(var a: TLoc; k: TLocKind; typ: PType; r: PRope;
|
||||||
flags: TLocFlags);
|
s: TStorageLoc);
|
||||||
begin
|
begin
|
||||||
// fills the loc if it is not already initialized
|
// fills the loc if it is not already initialized
|
||||||
if a.k = locNone then begin
|
if a.k = locNone then begin
|
||||||
a.k := k;
|
a.k := k;
|
||||||
if typ.kind = tyGenericInst then a.t := lastSon(typ) else a.t := typ;
|
a.t := getUniqueType(typ);
|
||||||
a.a := -1;
|
a.a := -1;
|
||||||
|
a.s := s;
|
||||||
if a.r = nil then a.r := r;
|
if a.r = nil then a.r := r;
|
||||||
a.flags := a.flags + flags
|
|
||||||
end
|
end
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure inheritStorage(var dest: TLoc; const src: TLoc);
|
function newProc(prc: PSym; module: BModule): BProc;
|
||||||
begin
|
|
||||||
dest.flags := src.flags * [lfOnStack, lfOnHeap, lfOnData, lfOnUnknown]
|
|
||||||
end;
|
|
||||||
|
|
||||||
function newProc(prc: PSym): BProc;
|
|
||||||
begin
|
begin
|
||||||
new(result);
|
new(result);
|
||||||
{@ignore}
|
{@ignore}
|
||||||
fillChar(result^, sizeof(result^), 0);
|
fillChar(result^, sizeof(result^), 0);
|
||||||
{@emit}
|
{@emit}
|
||||||
result.prc := prc;
|
result.prc := prc;
|
||||||
|
result.module := module;
|
||||||
if prc <> nil then
|
if prc <> nil then
|
||||||
result.options := prc.options
|
result.options := prc.options
|
||||||
else
|
else
|
||||||
|
|
@ -157,20 +171,19 @@ end;
|
||||||
|
|
||||||
function isSimpleConst(typ: PType): bool;
|
function isSimpleConst(typ: PType): bool;
|
||||||
begin
|
begin
|
||||||
result := not (skipAbstract(typ).kind in [tyRecord, tyRecordConstr,
|
result := not (skipVarGeneric(typ).kind in [tyTuple, tyObject, tyArray,
|
||||||
tyObject, tyArray,
|
|
||||||
tyArrayConstr, tySet, tySequence])
|
tyArrayConstr, tySet, tySequence])
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure useHeader(sym: PSym);
|
procedure useHeader(m: BModule; sym: PSym);
|
||||||
begin
|
begin
|
||||||
if lfHeader in sym.loc.Flags then begin
|
if lfHeader in sym.loc.Flags then begin
|
||||||
assert(sym.annex <> nil);
|
assert(sym.annex <> nil);
|
||||||
{@discard} lists.IncludeStr(currMod.headerFiles, PLib(sym.annex).path)
|
{@discard} lists.IncludeStr(m.headerFiles, PLib(sym.annex).path)
|
||||||
end
|
end
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure UseMagic(const name: string); forward;
|
procedure UseMagic(m: BModule; const name: string); forward;
|
||||||
|
|
||||||
// ----------------------------- name mangling
|
// ----------------------------- name mangling
|
||||||
// +++++++++++++++++++++++++++++ type generation
|
// +++++++++++++++++++++++++++++ type generation
|
||||||
|
|
@ -182,14 +195,14 @@ procedure UseMagic(const name: string); forward;
|
||||||
function beEqualTypes(a, b: PType): bool;
|
function beEqualTypes(a, b: PType): bool;
|
||||||
begin
|
begin
|
||||||
// returns whether two type are equal for the backend
|
// returns whether two type are equal for the backend
|
||||||
result := sameType(skipAbstract(a), skipAbstract(b))
|
result := sameType(skipGenericRange(a), skipGenericRange(b))
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function getTemp(p: BProc; t: PType): TLoc;
|
function getTemp(p: BProc; t: PType): TLoc;
|
||||||
var
|
var
|
||||||
i, index: int;
|
i, index: int;
|
||||||
name: PRope;
|
name: PRope;
|
||||||
begin
|
begin (*
|
||||||
for i := 0 to high(p.locals) do begin
|
for i := 0 to high(p.locals) do begin
|
||||||
assert(i = p.locals[i].a);
|
assert(i = p.locals[i].a);
|
||||||
if (p.locals[i].k = locNone) and beEqualTypes(p.locals[i].t, t) then begin
|
if (p.locals[i].k = locNone) and beEqualTypes(p.locals[i].t, t) then begin
|
||||||
|
|
@ -198,41 +211,41 @@ begin
|
||||||
result := p.locals[i];
|
result := p.locals[i];
|
||||||
exit
|
exit
|
||||||
end
|
end
|
||||||
end;
|
end; *)
|
||||||
// not found:
|
// not found:
|
||||||
index := length(p.locals);
|
index := length(p.locals);
|
||||||
setLength(p.locals, index+1);
|
setLength(p.locals, index+1);
|
||||||
// declare the new temporary:
|
// declare the new temporary:
|
||||||
name := con('Loc', toRope(index));
|
name := con('Loc', toRope(index));
|
||||||
appRopeFormat(p.s[cpsLocals], '$1 $2; /* temporary */$n',
|
appf(p.s[cpsLocals], '$1 $2; /* temporary */$n',
|
||||||
[getTypeDesc(t), name]);
|
[getTypeDesc(p.module, t), name]);
|
||||||
p.locals[index].k := locTemp;
|
p.locals[index].k := locTemp;
|
||||||
p.locals[index].a := index;
|
p.locals[index].a := index;
|
||||||
p.locals[index].r := name;
|
p.locals[index].r := name;
|
||||||
p.locals[index].t := t;
|
p.locals[index].t := getUniqueType(t);
|
||||||
p.locals[index].flags := {@set}[lfOnStack];
|
p.locals[index].s := OnStack;
|
||||||
|
p.locals[index].flags := {@set}[];
|
||||||
result := p.locals[index] // BUGFIX!
|
result := p.locals[index] // BUGFIX!
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure freeTemp(p: BProc; const temp: TLoc);
|
procedure freeTemp(p: BProc; const temp: TLoc);
|
||||||
begin
|
begin (*
|
||||||
if (temp.a >= 0) and (temp.a < length(p.locals)) and
|
if (temp.a >= 0) and (temp.a < length(p.locals)) and
|
||||||
(p.locals[temp.a].k = locTemp) then
|
(p.locals[temp.a].k = locTemp) then
|
||||||
p.locals[temp.a].k := locNone
|
p.locals[temp.a].k := locNone *)
|
||||||
end;
|
end;
|
||||||
|
|
||||||
// -------------------------- Variable manager ----------------------------
|
// -------------------------- Variable manager ----------------------------
|
||||||
|
|
||||||
procedure declareGlobalVar(s: PSym);
|
procedure declareGlobalVar(m: BModule; s: PSym);
|
||||||
begin
|
begin
|
||||||
if not IntSetContainsOrIncl(currMod.declaredThings, s.id) then begin
|
if not IntSetContainsOrIncl(m.declaredThings, s.id) then begin
|
||||||
app(currMod.s[cfsVars], getTypeDesc(s.loc.t));
|
app(m.s[cfsVars], getTypeDesc(m, s.loc.t));
|
||||||
if sfRegister in s.flags then
|
if sfRegister in s.flags then
|
||||||
app(currMod.s[cfsVars], ' register');
|
app(m.s[cfsVars], ' register');
|
||||||
if sfVolatile in s.flags then
|
if sfVolatile in s.flags then
|
||||||
app(currMod.s[cfsVars], ' volatile');
|
app(m.s[cfsVars], ' volatile');
|
||||||
appRopeFormat(currMod.s[cfsVars], ' $1; /* $2 */$n',
|
appf(m.s[cfsVars], ' $1;$n', [s.loc.r])
|
||||||
[s.loc.r, toRope(s.name.s)])
|
|
||||||
end
|
end
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
@ -241,39 +254,38 @@ begin
|
||||||
//assert(s.loc.k == locNone) // not yet assigned
|
//assert(s.loc.k == locNone) // not yet assigned
|
||||||
// this need not be fullfilled for inline procs; they are regenerated
|
// this need not be fullfilled for inline procs; they are regenerated
|
||||||
// for each module that uses them!
|
// for each module that uses them!
|
||||||
fillLoc(s.loc, locLocalVar, s.typ, mangleName(s), {@set}[lfOnStack]);
|
fillLoc(s.loc, locLocalVar, s.typ, mangleName(s), OnStack);
|
||||||
app(p.s[cpsLocals], getTypeDesc(s.loc.t));
|
app(p.s[cpsLocals], getTypeDesc(p.module, s.loc.t));
|
||||||
if sfRegister in s.flags then
|
if sfRegister in s.flags then
|
||||||
app(p.s[cpsLocals], ' register');
|
app(p.s[cpsLocals], ' register');
|
||||||
if (sfVolatile in s.flags) or (p.inTryStmt > 0) then
|
if (sfVolatile in s.flags) or (p.nestedTryStmts > 0) then
|
||||||
app(p.s[cpsLocals], ' volatile');
|
app(p.s[cpsLocals], ' volatile');
|
||||||
|
|
||||||
appRopeFormat(p.s[cpsLocals], ' $1; /* $2 */$n',
|
appf(p.s[cpsLocals], ' $1;$n', [s.loc.r]);
|
||||||
[s.loc.r, toRope(s.name.s)]);
|
|
||||||
// if debugging we need a new slot for the local variable:
|
// if debugging we need a new slot for the local variable:
|
||||||
if [optStackTrace, optEndb] * p.Options = [optStackTrace, optEndb] then begin
|
if [optStackTrace, optEndb] * p.Options = [optStackTrace, optEndb] then begin
|
||||||
appRopeFormat(p.s[cpsInit],
|
appf(p.s[cpsInit],
|
||||||
'F.s[$1].name = $2; F.s[$1].address = (void*)&$3; F.s[$1].typ = $4;$n',
|
'F.s[$1].name = $2; F.s[$1].address = (void*)&$3; F.s[$1].typ = $4;$n',
|
||||||
[toRope(p.frameLen), makeCString(normalize(s.name.s)), s.loc.r,
|
[toRope(p.frameLen), makeCString(normalize(s.name.s)), s.loc.r,
|
||||||
genTypeInfo(currMod, s.loc.t)]);
|
genTypeInfo(p.module, s.loc.t)]);
|
||||||
inc(p.frameLen);
|
inc(p.frameLen);
|
||||||
end
|
end
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure assignGlobalVar(s: PSym);
|
procedure assignGlobalVar(m: BModule; s: PSym);
|
||||||
begin
|
begin
|
||||||
fillLoc(s.loc, locGlobalVar, s.typ, mangleName(s), {@set}[lfOnData]);
|
fillLoc(s.loc, locGlobalVar, s.typ, mangleName(s), OnHeap);
|
||||||
useHeader(s);
|
useHeader(m, s);
|
||||||
if lfNoDecl in s.loc.flags then exit;
|
if lfNoDecl in s.loc.flags then exit;
|
||||||
if sfImportc in s.flags then app(currMod.s[cfsVars], 'extern ');
|
if sfImportc in s.flags then app(m.s[cfsVars], 'extern ');
|
||||||
declareGlobalVar(s);
|
declareGlobalVar(m, s);
|
||||||
if [optStackTrace, optEndb] * currMod.module.options =
|
if [optStackTrace, optEndb] * m.module.options =
|
||||||
[optStackTrace, optEndb] then begin
|
[optStackTrace, optEndb] then begin
|
||||||
useMagic('dbgRegisterGlobal');
|
useMagic(m, 'dbgRegisterGlobal');
|
||||||
appRopeFormat(currMod.s[cfsDebugInit],
|
appf(m.s[cfsDebugInit],
|
||||||
'dbgRegisterGlobal($1, &$2, $3);$n',
|
'dbgRegisterGlobal($1, &$2, $3);$n',
|
||||||
[makeCString(normalize(s.owner.name.s + '.' +{&} s.name.s)), s.loc.r,
|
[makeCString(normalize(s.owner.name.s + '.' +{&} s.name.s)), s.loc.r,
|
||||||
genTypeInfo(currMod, s.typ)])
|
genTypeInfo(m, s.typ)])
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
@ -286,12 +298,12 @@ procedure assignParam(p: BProc; s: PSym);
|
||||||
begin
|
begin
|
||||||
assert(s.loc.r <> nil);
|
assert(s.loc.r <> nil);
|
||||||
if [optStackTrace, optEndb] * p.options = [optStackTrace, optEndb] then begin
|
if [optStackTrace, optEndb] * p.options = [optStackTrace, optEndb] then begin
|
||||||
appRopeFormat(p.s[cpsInit],
|
appf(p.s[cpsInit],
|
||||||
'F.s[$1].name = $2; F.s[$1].address = (void*)$3; ' +
|
'F.s[$1].name = $2; F.s[$1].address = (void*)$3; ' +
|
||||||
'F.s[$1].typ = $4;$n',
|
'F.s[$1].typ = $4;$n',
|
||||||
[toRope(p.frameLen), makeCString(normalize(s.name.s)),
|
[toRope(p.frameLen), makeCString(normalize(s.name.s)),
|
||||||
iff(usePtrPassing(s), s.loc.r, con('&'+'', s.loc.r)),
|
iff(ccgIntroducedPtr(s), s.loc.r, con('&'+'', s.loc.r)),
|
||||||
genTypeInfo(currMod, s.loc.t)]);
|
genTypeInfo(p.module, s.loc.t)]);
|
||||||
inc(p.frameLen)
|
inc(p.frameLen)
|
||||||
end
|
end
|
||||||
end;
|
end;
|
||||||
|
|
@ -301,19 +313,19 @@ end;
|
||||||
// note that a label is a location too
|
// note that a label is a location too
|
||||||
function getLabel(p: BProc): TLabel;
|
function getLabel(p: BProc): TLabel;
|
||||||
begin
|
begin
|
||||||
inc(p.unique);
|
inc(p.labels);
|
||||||
result := con('L'+'', toRope(p.unique))
|
result := con('L'+'', toRope(p.labels))
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure fixLabel(p: BProc; labl: TLabel);
|
procedure fixLabel(p: BProc; labl: TLabel);
|
||||||
begin
|
begin
|
||||||
appRopeFormat(p.s[cpsStmts], '$1: ;$n', [labl])
|
appf(p.s[cpsStmts], '$1: ;$n', [labl])
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure genProcPrototype(sym: PSym); forward;
|
procedure genProcPrototype(m: BModule; sym: PSym); forward;
|
||||||
procedure genVarPrototype(sym: PSym); forward;
|
procedure genVarPrototype(m: BModule; sym: PSym); forward;
|
||||||
procedure genConstPrototype(sym: PSym); forward;
|
procedure genConstPrototype(m: BModule; sym: PSym); forward;
|
||||||
procedure genProc(prc: PSym); forward;
|
procedure genProc(m: BModule; prc: PSym); forward;
|
||||||
procedure genStmts(p: BProc; t: PNode); forward;
|
procedure genStmts(p: BProc; t: PNode); forward;
|
||||||
|
|
||||||
{$include 'ccgexprs.pas'}
|
{$include 'ccgexprs.pas'}
|
||||||
|
|
@ -323,76 +335,76 @@ procedure genStmts(p: BProc; t: PNode); forward;
|
||||||
|
|
||||||
// We don't finalize dynamic libs as this does the OS for us.
|
// We don't finalize dynamic libs as this does the OS for us.
|
||||||
|
|
||||||
procedure loadDynamicLib(lib: PLib);
|
procedure loadDynamicLib(m: BModule; lib: PLib);
|
||||||
var
|
var
|
||||||
tmp: PRope;
|
tmp: PRope;
|
||||||
begin
|
begin
|
||||||
assert(lib <> nil);
|
assert(lib <> nil);
|
||||||
if lib.kind = libDynamic then begin
|
if lib.kind = libDynamic then begin
|
||||||
lib.kind := libDynamicGenerated;
|
lib.kind := libDynamicGenerated;
|
||||||
useMagic('nimLoadLibrary');
|
useMagic(m, 'nimLoadLibrary');
|
||||||
useMagic('nimUnloadLibrary');
|
useMagic(m, 'nimUnloadLibrary');
|
||||||
tmp := getTempName();
|
tmp := getTempName();
|
||||||
appRopeFormat(currMod.s[cfsVars], 'static void* $1;$n', [tmp]);
|
appf(m.s[cfsVars], 'static void* $1;$n', [tmp]);
|
||||||
appRopeFormat(currMod.s[cfsDynLibInit],
|
appf(m.s[cfsDynLibInit],
|
||||||
'$1 = nimLoadLibrary((string) &$2);$n',
|
'$1 = nimLoadLibrary((string) &$2);$n',
|
||||||
[tmp, getStrLit(lib.path)]);
|
[tmp, getStrLit(m, lib.path)]);
|
||||||
appRopeFormat(currMod.s[cfsDynLibDeinit],
|
appf(m.s[cfsDynLibDeinit],
|
||||||
'if ($1 != NIM_NIL) nimUnloadLibrary($1);$n', [tmp]);
|
'if ($1 != NIM_NIL) nimUnloadLibrary($1);$n', [tmp]);
|
||||||
assert(lib.name = nil);
|
assert(lib.name = nil);
|
||||||
lib.name := tmp
|
lib.name := tmp
|
||||||
end
|
end
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure SymInDynamicLib(sym: PSym);
|
procedure SymInDynamicLib(m: BModule; sym: PSym);
|
||||||
var
|
var
|
||||||
lib: PLib;
|
lib: PLib;
|
||||||
extname, tmp: PRope;
|
extname, tmp: PRope;
|
||||||
begin
|
begin
|
||||||
lib := PLib(sym.annex);
|
lib := PLib(sym.annex);
|
||||||
extname := sym.loc.r;
|
extname := sym.loc.r;
|
||||||
loadDynamicLib(lib);
|
loadDynamicLib(m, lib);
|
||||||
useMagic('nimGetProcAddr');
|
useMagic(m, 'nimGetProcAddr');
|
||||||
tmp := ropeFormat('Dl_$1', [toRope(sym.id)]);
|
tmp := ropef('Dl_$1', [toRope(sym.id)]);
|
||||||
sym.loc.r := tmp; // from now on we only need the internal name
|
sym.loc.r := tmp; // from now on we only need the internal name
|
||||||
sym.typ.sym := nil; // generate a new name
|
sym.typ.sym := nil; // generate a new name
|
||||||
appRopeFormat(currMod.s[cfsDynLibInit],
|
appf(m.s[cfsDynLibInit],
|
||||||
'$1 = ($2) nimGetProcAddr($3, $4);$n',
|
'$1 = ($2) nimGetProcAddr($3, $4);$n',
|
||||||
[tmp, getTypeDesc(sym.typ), lib.name,
|
[tmp, getTypeDesc(m, sym.typ), lib.name,
|
||||||
makeCString(ropeToStr(extname))]);
|
makeCString(ropeToStr(extname))]);
|
||||||
declareGlobalVar(sym)
|
declareGlobalVar(m, sym)
|
||||||
end;
|
end;
|
||||||
|
|
||||||
// ----------------------------- sections ---------------------------------
|
// ----------------------------- sections ---------------------------------
|
||||||
|
|
||||||
procedure UseMagic(const name: string);
|
procedure UseMagic(m: BModule; const name: string);
|
||||||
var
|
var
|
||||||
sym: PSym;
|
sym: PSym;
|
||||||
begin
|
begin
|
||||||
if (sfSystemModule in currMod.module.flags) then exit;
|
if (sfSystemModule in m.module.flags) then exit;
|
||||||
// we don't know the magic symbols in the system module, but they will be
|
// we don't know the magic symbols in the system module, but they will be
|
||||||
// there anyway, because that is the way the code generator works
|
// there anyway, because that is the way the code generator works
|
||||||
sym := magicsys.getCompilerProc(name);
|
sym := magicsys.getCompilerProc(name);
|
||||||
case sym.kind of
|
case sym.kind of
|
||||||
skProc: genProcPrototype(sym);
|
skProc, skConverter: genProcPrototype(m, sym);
|
||||||
skVar: genVarPrototype(sym);
|
skVar: genVarPrototype(m, sym);
|
||||||
skType: {@discard} getTypeDesc(sym.typ);
|
skType: {@discard} getTypeDesc(m, sym.typ);
|
||||||
else InternalError('useMagic: ' + name)
|
else InternalError('useMagic: ' + name)
|
||||||
end
|
end
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure generateHeaders();
|
procedure generateHeaders(m: BModule);
|
||||||
var
|
var
|
||||||
it: PStrEntry;
|
it: PStrEntry;
|
||||||
begin
|
begin
|
||||||
app(currMod.s[cfsHeaders], '#include "nimbase.h"' +{&} tnl +{&} tnl);
|
app(m.s[cfsHeaders], '#include "nimbase.h"' +{&} tnl +{&} tnl);
|
||||||
it := PStrEntry(currMod.headerFiles.head);
|
it := PStrEntry(m.headerFiles.head);
|
||||||
while it <> nil do begin
|
while it <> nil do begin
|
||||||
if not (it.data[strStart] in ['"', '<']) then
|
if not (it.data[strStart] in ['"', '<']) then
|
||||||
appRopeFormat(currMod.s[cfsHeaders],
|
appf(m.s[cfsHeaders],
|
||||||
'#include "$1"$n', [toRope(it.data)])
|
'#include "$1"$n', [toRope(it.data)])
|
||||||
else
|
else
|
||||||
appRopeFormat(currMod.s[cfsHeaders], '#include $1$n', [toRope(it.data)]);
|
appf(m.s[cfsHeaders], '#include $1$n', [toRope(it.data)]);
|
||||||
it := PStrEntry(it.Next)
|
it := PStrEntry(it.Next)
|
||||||
end
|
end
|
||||||
end;
|
end;
|
||||||
|
|
@ -402,15 +414,15 @@ var
|
||||||
slots: PRope;
|
slots: PRope;
|
||||||
begin
|
begin
|
||||||
if p.frameLen > 0 then begin
|
if p.frameLen > 0 then begin
|
||||||
useMagic('TVarSlot');
|
useMagic(p.module, 'TVarSlot');
|
||||||
slots := ropeFormat(' TVarSlot s[$1];$n', [toRope(p.frameLen)])
|
slots := ropef(' TVarSlot s[$1];$n', [toRope(p.frameLen)])
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
slots := nil;
|
slots := nil;
|
||||||
appRopeFormat(p.s[cpsLocals], 'volatile struct {TFrame* prev;' +
|
appf(p.s[cpsLocals], 'volatile struct {TFrame* prev;' +
|
||||||
'NCSTRING procname;NS line;NCSTRING filename;' +
|
'NCSTRING procname;NI line;NCSTRING filename;' +
|
||||||
'NS len;$n$1} F;$n', [slots]);
|
'NI len;$n$1} F;$n', [slots]);
|
||||||
prepend(p.s[cpsInit], ropeFormat('F.len = $1;$n', [toRope(p.frameLen)]))
|
prepend(p.s[cpsInit], ropef('F.len = $1;$n', [toRope(p.frameLen)]))
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function retIsNotVoid(s: PSym): bool;
|
function retIsNotVoid(s: PSym): bool;
|
||||||
|
|
@ -418,27 +430,27 @@ begin
|
||||||
result := (s.typ.sons[0] <> nil) and not isInvalidReturnType(s.typ.sons[0])
|
result := (s.typ.sons[0] <> nil) and not isInvalidReturnType(s.typ.sons[0])
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure genProc(prc: PSym);
|
procedure genProc(m: BModule; prc: PSym);
|
||||||
var
|
var
|
||||||
p: BProc;
|
p: BProc;
|
||||||
generatedProc, header, returnStmt: PRope;
|
generatedProc, header, returnStmt: PRope;
|
||||||
i: int;
|
i: int;
|
||||||
res, param: PSym;
|
res, param: PSym;
|
||||||
begin
|
begin
|
||||||
useHeader(prc);
|
useHeader(m, prc);
|
||||||
fillLoc(prc.loc, locProc, prc.typ, mangleName(prc), {@set}[lfOnData]);
|
fillLoc(prc.loc, locProc, prc.typ, mangleName(prc), OnStack);
|
||||||
if (lfNoDecl in prc.loc.Flags) then exit;
|
if (lfNoDecl in prc.loc.Flags) then exit;
|
||||||
if lfDynamicLib in prc.loc.flags then
|
if lfDynamicLib in prc.loc.flags then
|
||||||
SymInDynamicLib(prc)
|
SymInDynamicLib(m, prc)
|
||||||
else if not (sfImportc in prc.flags) then begin
|
else if not (sfImportc in prc.flags) then begin
|
||||||
// we have a real proc here:
|
// we have a real proc here:
|
||||||
p := newProc(prc);
|
p := newProc(prc, m);
|
||||||
header := genProcHeader(prc);
|
header := genProcHeader(m, prc);
|
||||||
if (sfCompilerProc in prc.flags)
|
if (sfCompilerProc in prc.flags)
|
||||||
and (sfSystemModule in currMod.module.flags)
|
and (sfSystemModule in m.module.flags)
|
||||||
and not IntSetContains(currMod.declaredThings, prc.id) then
|
and not IntSetContains(m.declaredThings, prc.id) then
|
||||||
appRopeFormat(currMod.s[cfsProcHeaders], '$1;$n', [header]);
|
appf(m.s[cfsProcHeaders], '$1;$n', [header]);
|
||||||
intSetIncl(currMod.declaredThings, prc.id);
|
intSetIncl(m.declaredThings, prc.id);
|
||||||
returnStmt := nil;
|
returnStmt := nil;
|
||||||
assert(prc.ast <> nil);
|
assert(prc.ast <> nil);
|
||||||
|
|
||||||
|
|
@ -450,7 +462,7 @@ begin
|
||||||
assert(res.loc.r <> nil);
|
assert(res.loc.r <> nil);
|
||||||
initVariable(p, res);
|
initVariable(p, res);
|
||||||
genObjectInit(p, res);
|
genObjectInit(p, res);
|
||||||
returnStmt := ropeFormat('return $1;$n', [rdLoc(res.loc)]);
|
returnStmt := ropef('return $1;$n', [rdLoc(res.loc)]);
|
||||||
end
|
end
|
||||||
else if (prc.typ.sons[0] <> nil) then begin
|
else if (prc.typ.sons[0] <> nil) then begin
|
||||||
res := prc.ast.sons[resultPos].sym; // get result symbol
|
res := prc.ast.sons[resultPos].sym; // get result symbol
|
||||||
|
|
@ -465,13 +477,13 @@ begin
|
||||||
|
|
||||||
genStmts(p, prc.ast.sons[codePos]); // modifies p.locals, p.init, etc.
|
genStmts(p, prc.ast.sons[codePos]); // modifies p.locals, p.init, etc.
|
||||||
if sfPure in prc.flags then
|
if sfPure in prc.flags then
|
||||||
generatedProc := ropeFormat('$1 {$n$2$3$4}$n',
|
generatedProc := ropef('$1 {$n$2$3$4}$n',
|
||||||
[header, p.s[cpsLocals], p.s[cpsInit], p.s[cpsStmts]])
|
[header, p.s[cpsLocals], p.s[cpsInit], p.s[cpsStmts]])
|
||||||
else begin
|
else begin
|
||||||
generatedProc := con(header, '{' + tnl);
|
generatedProc := con(header, '{' + tnl);
|
||||||
if optStackTrace in prc.options then begin
|
if optStackTrace in prc.options then begin
|
||||||
getFrameDecl(p);
|
getFrameDecl(p);
|
||||||
prepend(p.s[cpsInit], ropeFormat(
|
prepend(p.s[cpsInit], ropef(
|
||||||
'F.procname = $1;$n' +
|
'F.procname = $1;$n' +
|
||||||
'F.prev = framePtr;$n' +
|
'F.prev = framePtr;$n' +
|
||||||
'F.filename = $2;$n' +
|
'F.filename = $2;$n' +
|
||||||
|
|
@ -491,86 +503,93 @@ begin
|
||||||
//if prc.typ.callConv <> ccInline then
|
//if prc.typ.callConv <> ccInline then
|
||||||
// prc.ast.sons[codePos] := nil;
|
// prc.ast.sons[codePos] := nil;
|
||||||
end;
|
end;
|
||||||
app(currMod.s[cfsProcs], generatedProc);
|
app(m.s[cfsProcs], generatedProc);
|
||||||
end
|
end
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure genVarPrototype(sym: PSym);
|
procedure genVarPrototype(m: BModule; sym: PSym);
|
||||||
begin
|
begin
|
||||||
assert(sfGlobal in sym.flags);
|
assert(sfGlobal in sym.flags);
|
||||||
useHeader(sym);
|
useHeader(m, sym);
|
||||||
fillLoc(sym.loc, locGlobalVar, sym.typ, mangleName(sym), {@set}[lfOnData]);
|
fillLoc(sym.loc, locGlobalVar, sym.typ, mangleName(sym), OnHeap);
|
||||||
if (lfNoDecl in sym.loc.Flags) or
|
if (lfNoDecl in sym.loc.Flags) or
|
||||||
intSetContainsOrIncl(currMod.declaredThings, sym.id) then
|
intSetContainsOrIncl(m.declaredThings, sym.id) then
|
||||||
exit;
|
exit;
|
||||||
if sym.owner.id <> currMod.module.id then begin
|
if sym.owner.id <> m.module.id then begin
|
||||||
// else we already have the symbol generated!
|
// else we already have the symbol generated!
|
||||||
assert(sym.loc.r <> nil);
|
assert(sym.loc.r <> nil);
|
||||||
app(currMod.s[cfsVars], 'extern ');
|
app(m.s[cfsVars], 'extern ');
|
||||||
app(currMod.s[cfsVars], getTypeDesc(sym.loc.t));
|
app(m.s[cfsVars], getTypeDesc(m, sym.loc.t));
|
||||||
if sfRegister in sym.flags then
|
if sfRegister in sym.flags then
|
||||||
app(currMod.s[cfsVars], ' register');
|
app(m.s[cfsVars], ' register');
|
||||||
if sfVolatile in sym.flags then
|
if sfVolatile in sym.flags then
|
||||||
app(currMod.s[cfsVars], ' volatile');
|
app(m.s[cfsVars], ' volatile');
|
||||||
appRopeFormat(currMod.s[cfsVars], ' $1; /* $2 */$n',
|
appf(m.s[cfsVars], ' $1;$n', [sym.loc.r])
|
||||||
[sym.loc.r, toRope(sym.name.s)])
|
|
||||||
end
|
end
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure genConstPrototype(sym: PSym);
|
procedure genConstPrototype(m: BModule; sym: PSym);
|
||||||
begin
|
begin
|
||||||
useHeader(sym);
|
useHeader(m, sym);
|
||||||
fillLoc(sym.loc, locData, sym.typ, mangleName(sym), {@set}[lfOnData]);
|
fillLoc(sym.loc, locData, sym.typ, mangleName(sym), OnUnknown);
|
||||||
if (lfNoDecl in sym.loc.Flags) or
|
if (lfNoDecl in sym.loc.Flags) or
|
||||||
intSetContainsOrIncl(currMod.declaredThings, sym.id) then
|
intSetContainsOrIncl(m.declaredThings, sym.id) then
|
||||||
exit;
|
exit;
|
||||||
if sym.owner.id <> currMod.module.id then begin
|
if sym.owner.id <> m.module.id then begin
|
||||||
// else we already have the symbol generated!
|
// else we already have the symbol generated!
|
||||||
assert(sym.loc.r <> nil);
|
assert(sym.loc.r <> nil);
|
||||||
app(currMod.s[cfsData], 'extern ');
|
app(m.s[cfsData], 'extern ');
|
||||||
appRopeFormat(currMod.s[cfsData], '$1$2 $3; /* $4 */$n',
|
appf(m.s[cfsData], 'NIM_CONST $1 $2;$n',
|
||||||
[constTok, getTypeDesc(sym.loc.t), sym.loc.r, toRope(sym.name.s)])
|
[getTypeDesc(m, sym.loc.t), sym.loc.r])
|
||||||
end
|
end
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure genProcPrototype(sym: PSym);
|
procedure genProcPrototype(m: BModule; sym: PSym);
|
||||||
begin
|
begin
|
||||||
useHeader(sym);
|
useHeader(m, sym);
|
||||||
fillLoc(sym.loc, locProc, sym.typ, mangleName(sym), {@set}[lfOnData]);
|
fillLoc(sym.loc, locProc, sym.typ, mangleName(sym), OnStack);
|
||||||
if lfDynamicLib in sym.loc.Flags then begin
|
if lfDynamicLib in sym.loc.Flags then begin
|
||||||
// it is a proc variable!
|
// it is a proc variable!
|
||||||
if (sym.owner.id <> currMod.module.id) and
|
if (sym.owner.id <> m.module.id) and
|
||||||
not intSetContainsOrIncl(currMod.declaredThings, sym.id) then begin
|
not intSetContainsOrIncl(m.declaredThings, sym.id) then begin
|
||||||
app(currMod.s[cfsVars], 'extern ');
|
app(m.s[cfsVars], 'extern ');
|
||||||
// BUGFIX: declareGlobalVar() inlined, because of intSetContainsOrIncl
|
// BUGFIX: declareGlobalVar() inlined, because of intSetContainsOrIncl
|
||||||
// check
|
// check
|
||||||
app(currMod.s[cfsVars], getTypeDesc(sym.loc.t));
|
app(m.s[cfsVars], getTypeDesc(m, sym.loc.t));
|
||||||
appRopeFormat(currMod.s[cfsVars], ' $1; /* $2 */$n',
|
appf(m.s[cfsVars], ' $1;$n', [sym.loc.r])
|
||||||
[sym.loc.r, toRope(sym.name.s)])
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
else begin
|
else begin
|
||||||
// it is a proc:
|
// it is a proc:
|
||||||
if (lfNoDecl in sym.loc.Flags) then exit;
|
if (lfNoDecl in sym.loc.Flags) then exit;
|
||||||
if intSetContainsOrIncl(currMod.declaredThings, sym.id) then exit;
|
if intSetContainsOrIncl(m.declaredThings, sym.id) then exit;
|
||||||
appRopeFormat(currMod.s[cfsProcHeaders], '$1;$n', [genProcHeader(sym)]);
|
appf(m.s[cfsProcHeaders], '$1;$n', [genProcHeader(m, sym)]);
|
||||||
if (sym.typ.callConv = ccInline)
|
if (sym.typ.callConv = ccInline)
|
||||||
and (sym.owner.id <> currMod.module.id) then
|
and (sym.owner.id <> m.module.id) then
|
||||||
genProc(sym) // generate the code again!
|
genProc(m, sym) // generate the code again!
|
||||||
// else
|
|
||||||
// IntSetIncl(currMod.declaredThings, sym.id)
|
|
||||||
end
|
end
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function getFileHeader: PRope;
|
function getFileHeader(const cfilenoext: string): PRope;
|
||||||
begin
|
begin
|
||||||
result := ropeFormat(
|
result := ropef(
|
||||||
'/* Generated by the Nimrod Compiler v$1 */$n' +
|
'/* Generated by the Nimrod Compiler v$1 */$n' +
|
||||||
'/* (c) 2008 Andreas Rumpf */$n' +
|
'/* (c) 2008 Andreas Rumpf */$n' +
|
||||||
'/* Compiled for: $2, $3, $4 */$n',
|
'/* Compiled for: $2, $3, $4 */$n' +
|
||||||
|
'/* Command for C compiler:$n $5 */$n',
|
||||||
[toRope(versionAsString), toRope(platform.OS[targetOS].name),
|
[toRope(versionAsString), toRope(platform.OS[targetOS].name),
|
||||||
toRope(platform.CPU[targetCPU].name),
|
toRope(platform.CPU[targetCPU].name),
|
||||||
toRope(extccomp.CC[extccomp.ccompiler].name)])
|
toRope(extccomp.CC[extccomp.ccompiler].name),
|
||||||
|
toRope(getCompileCFileCmd(cfilenoext))]);
|
||||||
|
case platform.CPU[targetCPU].intSize of
|
||||||
|
16: appf(result, '$ntypedef short int NI;$n' +
|
||||||
|
'typedef unsigned short int NU;$n', []);
|
||||||
|
32: appf(result, '$ntypedef long int NI;$n' +
|
||||||
|
'typedef unsigned long int NU;$n', []);
|
||||||
|
64: appf(result, '$ntypedef long long int NI;$n' +
|
||||||
|
'typedef unsigned long long int NU;$n', []);
|
||||||
|
else begin end
|
||||||
|
end
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure genMainProc(m: BModule);
|
procedure genMainProc(m: BModule);
|
||||||
|
|
@ -581,13 +600,13 @@ const
|
||||||
'$1' +
|
'$1' +
|
||||||
'$2';
|
'$2';
|
||||||
PosixMain =
|
PosixMain =
|
||||||
'NS cmdCount;$n' +
|
'NI cmdCount;$n' +
|
||||||
'char** cmdLine;$n' +
|
'char** cmdLine;$n' +
|
||||||
'char** gEnv;$n' +
|
'char** gEnv;$n' +
|
||||||
'int main(int argc, char** args, char** env) {$n' +
|
'int main(int argc, char** args, char** env) {$n' +
|
||||||
' int dummy[8];$n' +
|
' int dummy[8];$n' +
|
||||||
' cmdLine = args;$n' +
|
' cmdLine = args;$n' +
|
||||||
' cmdCount = (NS)argc;$n' +
|
' cmdCount = (NI)argc;$n' +
|
||||||
' gEnv = env;$n' +{&}
|
' gEnv = env;$n' +{&}
|
||||||
CommonMainBody +{&}
|
CommonMainBody +{&}
|
||||||
' return 0;$n' +
|
' return 0;$n' +
|
||||||
|
|
@ -610,7 +629,7 @@ const
|
||||||
var
|
var
|
||||||
frmt: TFormatStr;
|
frmt: TFormatStr;
|
||||||
begin
|
begin
|
||||||
useMagic('setStackBottom');
|
useMagic(m, 'setStackBottom');
|
||||||
if (platform.targetOS = osWindows) and
|
if (platform.targetOS = osWindows) and
|
||||||
(gGlobalOptions * [optGenGuiApp, optGenDynLib] <> []) then begin
|
(gGlobalOptions * [optGenGuiApp, optGenDynLib] <> []) then begin
|
||||||
if optGenGuiApp in gGlobalOptions then
|
if optGenGuiApp in gGlobalOptions then
|
||||||
|
|
@ -622,8 +641,8 @@ begin
|
||||||
else
|
else
|
||||||
frmt := PosixMain;
|
frmt := PosixMain;
|
||||||
if gBreakpoints <> nil then
|
if gBreakpoints <> nil then
|
||||||
useMagic('dbgRegisterBreakpoint');
|
useMagic(m, 'dbgRegisterBreakpoint');
|
||||||
appRopeFormat(m.s[cfsProcs], frmt, [gBreakpoints, mainModInit])
|
appf(m.s[cfsProcs], frmt, [gBreakpoints, mainModInit])
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure genInitCode(m: BModule);
|
procedure genInitCode(m: BModule);
|
||||||
|
|
@ -631,16 +650,16 @@ var
|
||||||
initname, prc: PRope;
|
initname, prc: PRope;
|
||||||
begin
|
begin
|
||||||
initname := con(m.module.name.s, toRope('Init'));
|
initname := con(m.module.name.s, toRope('Init'));
|
||||||
appRopeFormat(mainModProcs, 'N_NIMCALL(void, $1)(void);$n',
|
appf(mainModProcs, 'N_NIMCALL(void, $1)(void);$n',
|
||||||
[initname]);
|
[initname]);
|
||||||
if not (sfSystemModule in m.module.flags) then
|
if not (sfSystemModule in m.module.flags) then
|
||||||
appRopeFormat(mainModInit, '$1();$n', [initname]);
|
appf(mainModInit, '$1();$n', [initname]);
|
||||||
prc := ropeFormat('N_NIMCALL(void, $1)(void) {$n', [initname]);
|
prc := ropef('N_NIMCALL(void, $1)(void) {$n', [initname]);
|
||||||
if optStackTrace in m.initProc.options then begin
|
if optStackTrace in m.initProc.options then begin
|
||||||
prepend(m.initProc.s[cpsLocals], toRope('volatile TFrame F;' + tnl));
|
prepend(m.initProc.s[cpsLocals], toRope('volatile TFrame F;' + tnl));
|
||||||
app(prc, m.initProc.s[cpsLocals]);
|
app(prc, m.initProc.s[cpsLocals]);
|
||||||
app(prc, m.s[cfsTypeInit1]);
|
app(prc, m.s[cfsTypeInit1]);
|
||||||
appRopeFormat(prc,
|
appf(prc,
|
||||||
'F.len = 0;$n' + // IMPORTANT: else the debugger crashes!
|
'F.len = 0;$n' + // IMPORTANT: else the debugger crashes!
|
||||||
'F.procname = $1;$n' +
|
'F.procname = $1;$n' +
|
||||||
'F.prev = framePtr;$n' +
|
'F.prev = framePtr;$n' +
|
||||||
|
|
@ -666,12 +685,12 @@ begin
|
||||||
app(m.s[cfsProcs], prc)
|
app(m.s[cfsProcs], prc)
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function genModule(m: BModule): PRope;
|
function genModule(m: BModule; const cfilenoext: string): PRope;
|
||||||
var
|
var
|
||||||
i: TCFileSection;
|
i: TCFileSection;
|
||||||
begin
|
begin
|
||||||
result := getFileHeader();
|
result := getFileHeader(cfilenoext);
|
||||||
generateHeaders();
|
generateHeaders(m);
|
||||||
for i := low(TCFileSection) to cfsProcs do app(result, m.s[i])
|
for i := low(TCFileSection) to cfsProcs do app(result, m.s[i])
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
@ -688,11 +707,10 @@ begin
|
||||||
initIdTable(result.typeCache);
|
initIdTable(result.typeCache);
|
||||||
initIdTable(result.forwTypeCache);
|
initIdTable(result.forwTypeCache);
|
||||||
result.module := module;
|
result.module := module;
|
||||||
if gCmd <> cmdCompileToCpp then
|
|
||||||
constTok := toRope('const ');
|
|
||||||
intSetInit(result.typeInfoMarker);
|
intSetInit(result.typeInfoMarker);
|
||||||
result.initProc := newProc(nil);
|
result.initProc := newProc(nil, result);
|
||||||
result.initProc.options := gOptions;
|
result.initProc.options := gOptions;
|
||||||
|
{@emit result.typeStack := [];}
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function shouldRecompile(code: PRope; const cfile, cfilenoext: string): bool;
|
function shouldRecompile(code: PRope; const cfile, cfilenoext: string): bool;
|
||||||
|
|
@ -717,28 +735,27 @@ var
|
||||||
code: PRope;
|
code: PRope;
|
||||||
begin
|
begin
|
||||||
m := BModule(b);
|
m := BModule(b);
|
||||||
currMod := m;
|
m.initProc.options := gOptions;
|
||||||
currMod.initProc.options := gOptions;
|
genStmts(m.initProc, n);
|
||||||
genStmts(currMod.initProc, n);
|
|
||||||
// generate code for the init statements of the module:
|
// generate code for the init statements of the module:
|
||||||
genInitCode(m);
|
genInitCode(m);
|
||||||
|
finishTypeDescriptions(m);
|
||||||
if sfMainModule in m.module.flags then begin
|
if sfMainModule in m.module.flags then begin
|
||||||
// generate mapping file (if requested):
|
// generate mapping file (if requested):
|
||||||
if gMapping <> nil then
|
if gMapping <> nil then
|
||||||
WriteRope(gMapping, ChangeFileExt(cfile + '_map', 'txt'));
|
WriteRope(gMapping, ChangeFileExt(cfile + '_map', 'txt'));
|
||||||
|
|
||||||
// generate main file:
|
// generate main file:
|
||||||
app(currMod.s[cfsProcHeaders], mainModProcs);
|
app(m.s[cfsProcHeaders], mainModProcs);
|
||||||
genMainProc(currMod);
|
genMainProc(m);
|
||||||
end;
|
end;
|
||||||
cfile := completeCFilePath(m.cfilename);
|
cfile := completeCFilePath(m.cfilename);
|
||||||
cfilenoext := changeFileExt(cfile, '');
|
cfilenoext := changeFileExt(cfile, '');
|
||||||
code := genModule(m);
|
code := genModule(m, cfilenoext);
|
||||||
if shouldRecompile(code, changeFileExt(cfile, cExt), cfilenoext) then begin
|
if shouldRecompile(code, changeFileExt(cfile, cExt), cfilenoext) then begin
|
||||||
addFileToCompile(cfilenoext); // is to compile
|
addFileToCompile(cfilenoext); // is to compile
|
||||||
end;
|
end;
|
||||||
addFileToLink(cfilenoext);
|
addFileToLink(cfilenoext);
|
||||||
currMod := nil // free the memory
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function CBackend(b: PBackend; module: PSym; const filename: string): PBackend;
|
function CBackend(b: PBackend; module: PSym; const filename: string): PBackend;
|
||||||
|
|
@ -749,7 +766,6 @@ begin
|
||||||
g.backendCreator := CBackend;
|
g.backendCreator := CBackend;
|
||||||
g.eventMask := {@set}[eAfterModule];
|
g.eventMask := {@set}[eAfterModule];
|
||||||
g.afterModuleEvent := finishModule;
|
g.afterModuleEvent := finishModule;
|
||||||
currMod := g;
|
|
||||||
result := g;
|
result := g;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -7,10 +7,10 @@
|
||||||
// distribution, for details about the copyright.
|
// distribution, for details about the copyright.
|
||||||
//
|
//
|
||||||
|
|
||||||
// This module handles the parsing of command line arguments.
|
|
||||||
|
|
||||||
unit commands;
|
unit commands;
|
||||||
|
|
||||||
|
// This module handles the parsing of command line arguments.
|
||||||
|
|
||||||
interface
|
interface
|
||||||
|
|
||||||
{$include 'config.inc'}
|
{$include 'config.inc'}
|
||||||
|
|
@ -41,16 +41,14 @@ uses
|
||||||
const
|
const
|
||||||
{$ifdef fpc}
|
{$ifdef fpc}
|
||||||
compileDate = {$I %date%};
|
compileDate = {$I %date%};
|
||||||
compileTime = {$I %time%};
|
|
||||||
{$else}
|
{$else}
|
||||||
compileDate = '2008-0-0';
|
compileDate = '2008-0-0';
|
||||||
compileTime = '00:00:00';
|
|
||||||
{$endif}
|
{$endif}
|
||||||
{@emit}
|
{@emit}
|
||||||
|
|
||||||
const
|
const
|
||||||
HelpMessage = 'Nimrod Compiler Version $1 (' +{&}
|
HelpMessage = 'Nimrod Compiler Version $1 (' +{&}
|
||||||
compileDate +{&} ' ' +{&} compileTime +{&} ') [$2: $3]' +{&} nl +{&}
|
compileDate +{&} ') [$2: $3]' +{&} nl +{&}
|
||||||
'Copyright (c) 2004-2008 by Andreas Rumpf' +{&} nl;
|
'Copyright (c) 2004-2008 by Andreas Rumpf' +{&} nl;
|
||||||
|
|
||||||
const
|
const
|
||||||
|
|
@ -66,6 +64,7 @@ const
|
||||||
+{&} ' compile compile project with default code generator (C)' +{&} nl
|
+{&} ' compile compile project with default code generator (C)' +{&} nl
|
||||||
+{&} ' compile_to_c compile project with C code generator' +{&} nl
|
+{&} ' compile_to_c compile project with C code generator' +{&} nl
|
||||||
+{&} ' compile_to_cpp compile project with C++ code generator' +{&} nl
|
+{&} ' compile_to_cpp compile project with C++ code generator' +{&} nl
|
||||||
|
+{&} ' compile_to_ecmascript compile project to ECMAScript code (experimental)' +{&} nl
|
||||||
+{&} ' doc generate the documentation for inputfile;' +{&} nl
|
+{&} ' doc generate the documentation for inputfile;' +{&} nl
|
||||||
+{&} ' with --run switch opens it with $BROWSER' +{&} nl
|
+{&} ' with --run switch opens it with $BROWSER' +{&} nl
|
||||||
+{&} 'Arguments:' +{&} nl
|
+{&} 'Arguments:' +{&} nl
|
||||||
|
|
@ -80,6 +79,8 @@ const
|
||||||
+{&} ' --line_trace:on|off code generation for line trace ON|OFF' +{&} nl
|
+{&} ' --line_trace:on|off code generation for line trace ON|OFF' +{&} nl
|
||||||
+{&} ' --debugger:on|off turn Embedded Nimrod Debugger ON|OFF' +{&} nl
|
+{&} ' --debugger:on|off turn Embedded Nimrod Debugger ON|OFF' +{&} nl
|
||||||
+{&} ' -x, --checks:on|off code generation for all runtime checks ON|OFF' +{&} nl
|
+{&} ' -x, --checks:on|off code generation for all runtime checks ON|OFF' +{&} nl
|
||||||
|
+{&} ' --obj_checks:on|off code generation for obj conversion checks ON|OFF' +{&} nl
|
||||||
|
+{&} ' --field_checks:on|off code generation for case record fields ON|OFF' +{&} nl
|
||||||
+{&} ' --range_checks:on|off code generation for range checks ON|OFF' +{&} nl
|
+{&} ' --range_checks:on|off code generation for range checks ON|OFF' +{&} nl
|
||||||
+{&} ' --bound_checks:on|off code generation for bound checks ON|OFF' +{&} nl
|
+{&} ' --bound_checks:on|off code generation for bound checks ON|OFF' +{&} nl
|
||||||
+{&} ' --overflow_checks:on|off code generation for over-/underflow checks ON|OFF' +{&} nl
|
+{&} ' --overflow_checks:on|off code generation for over-/underflow checks ON|OFF' +{&} nl
|
||||||
|
|
@ -174,17 +175,8 @@ const
|
||||||
;
|
;
|
||||||
|
|
||||||
function getCommandLineDesc: string;
|
function getCommandLineDesc: string;
|
||||||
var
|
|
||||||
v: string;
|
|
||||||
begin
|
begin
|
||||||
// the Pascal version number gets a little star ('*'), the Nimrod version
|
result := format(HelpMessage, [VersionAsString, platform.os[hostOS].name,
|
||||||
// does not! This helps distinguishing the different builds.
|
|
||||||
{@ignore}
|
|
||||||
v := VersionAsString +{&} '*';
|
|
||||||
{@emit
|
|
||||||
v := VersionAsString
|
|
||||||
}
|
|
||||||
result := format(HelpMessage, [v, platform.os[hostOS].name,
|
|
||||||
cpu[hostCPU].name]) +{&} Usage
|
cpu[hostCPU].name]) +{&} Usage
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
@ -210,6 +202,7 @@ begin
|
||||||
cpu[hostCPU].name]) +{&} AdvancedUsage);
|
cpu[hostCPU].name]) +{&} AdvancedUsage);
|
||||||
advHelpWritten := true;
|
advHelpWritten := true;
|
||||||
helpWritten := true;
|
helpWritten := true;
|
||||||
|
halt(0);
|
||||||
end
|
end
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
@ -423,7 +416,7 @@ begin
|
||||||
ProcessOnOffSwitch({@set}[optHints], arg, pass, info);
|
ProcessOnOffSwitch({@set}[optHints], arg, pass, info);
|
||||||
wCheckpoints:
|
wCheckpoints:
|
||||||
ProcessOnOffSwitch({@set}[optCheckpoints], arg, pass, info);
|
ProcessOnOffSwitch({@set}[optCheckpoints], arg, pass, info);
|
||||||
wStackTrace, wS:
|
wStackTrace:
|
||||||
ProcessOnOffSwitch({@set}[optStackTrace], arg, pass, info);
|
ProcessOnOffSwitch({@set}[optStackTrace], arg, pass, info);
|
||||||
wLineTrace:
|
wLineTrace:
|
||||||
ProcessOnOffSwitch({@set}[optLineTrace], arg, pass, info);
|
ProcessOnOffSwitch({@set}[optLineTrace], arg, pass, info);
|
||||||
|
|
@ -436,6 +429,10 @@ begin
|
||||||
end;
|
end;
|
||||||
wChecks, wX:
|
wChecks, wX:
|
||||||
ProcessOnOffSwitch(checksOptions, arg, pass, info);
|
ProcessOnOffSwitch(checksOptions, arg, pass, info);
|
||||||
|
wObjChecks:
|
||||||
|
ProcessOnOffSwitch({@set}[optObjCheck], arg, pass, info);
|
||||||
|
wFieldChecks:
|
||||||
|
ProcessOnOffSwitch({@set}[optFieldCheck], arg, pass, info);
|
||||||
wRangeChecks:
|
wRangeChecks:
|
||||||
ProcessOnOffSwitch({@set}[optRangeCheck], arg, pass, info);
|
ProcessOnOffSwitch({@set}[optRangeCheck], arg, pass, info);
|
||||||
wBoundChecks:
|
wBoundChecks:
|
||||||
|
|
@ -485,6 +482,10 @@ begin
|
||||||
liMessage(info, errGuiConsoleOrLibExpectedButXFound, arg)
|
liMessage(info, errGuiConsoleOrLibExpectedButXFound, arg)
|
||||||
end
|
end
|
||||||
end;
|
end;
|
||||||
|
wListDef: begin
|
||||||
|
if pass in {@set}[passCmd2, passPP] then
|
||||||
|
condsyms.listSymbols();
|
||||||
|
end;
|
||||||
wPassC, wT: begin
|
wPassC, wT: begin
|
||||||
expectArg(switch, arg, pass, info);
|
expectArg(switch, arg, pass, info);
|
||||||
if pass in {@set}[passCmd2, passPP] then
|
if pass in {@set}[passCmd2, passPP] then
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,7 @@ type
|
||||||
TCrc32 = int32;
|
TCrc32 = int32;
|
||||||
|
|
||||||
const
|
const
|
||||||
InitCrc32 = TCrc32($ffffffff);
|
InitCrc32 = TCrc32(-1);
|
||||||
|
|
||||||
function updateCrc32(val: Byte; crc: TCrc32): TCrc32; overload;
|
function updateCrc32(val: Byte; crc: TCrc32): TCrc32; overload;
|
||||||
function updateCrc32(val: Char; crc: TCrc32): TCrc32; overload;
|
function updateCrc32(val: Char; crc: TCrc32): TCrc32; overload;
|
||||||
|
|
|
||||||
169
nim/docgen.pas
169
nim/docgen.pas
|
|
@ -40,6 +40,7 @@ type
|
||||||
modDesc: PRope; // module description
|
modDesc: PRope; // module description
|
||||||
dependsOn: PRope; // dependencies
|
dependsOn: PRope; // dependencies
|
||||||
id: int; // for generating IDs
|
id: int; // for generating IDs
|
||||||
|
splitAfter: int; // split to long entries in the TOC
|
||||||
tocPart: array of TTocEntry;
|
tocPart: array of TTocEntry;
|
||||||
hasToc: bool;
|
hasToc: bool;
|
||||||
toc, section: TSections;
|
toc, section: TSections;
|
||||||
|
|
@ -106,6 +107,8 @@ begin
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function newDocumentor(const filename: string): PDoc;
|
function newDocumentor(const filename: string): PDoc;
|
||||||
|
var
|
||||||
|
s: string;
|
||||||
begin
|
begin
|
||||||
new(result);
|
new(result);
|
||||||
{@ignore}
|
{@ignore}
|
||||||
|
|
@ -115,6 +118,10 @@ begin
|
||||||
}
|
}
|
||||||
result.filename := filename;
|
result.filename := filename;
|
||||||
result.id := 100;
|
result.id := 100;
|
||||||
|
result.splitAfter := 25;
|
||||||
|
s := getConfigVar('split.item.toc');
|
||||||
|
if s <> '' then
|
||||||
|
result.splitAfter := parseInt(s);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function getVarIdx(const varnames: array of string; const id: string): int;
|
function getVarIdx(const varnames: array of string; const id: string): int;
|
||||||
|
|
@ -209,12 +216,16 @@ begin
|
||||||
end
|
end
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function toXml(const s: string): string;
|
function toXml(const s: string; splitAfter: int = -1): string;
|
||||||
var
|
var
|
||||||
i: int;
|
i: int;
|
||||||
begin
|
begin
|
||||||
result := '';
|
result := '';
|
||||||
for i := strStart to length(s)+strStart-1 do addXmlChar(result, s[i])
|
for i := strStart to length(s)+strStart-1 do begin
|
||||||
|
if (splitAfter >= 0) and ((i-strStart+1) mod splitAfter = 0) then
|
||||||
|
addChar(result, ' ');
|
||||||
|
addXmlChar(result, s[i])
|
||||||
|
end
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function renderRstToHtml(d: PDoc; n: PRstNode): PRope; forward;
|
function renderRstToHtml(d: PDoc; n: PRstNode): PRope; forward;
|
||||||
|
|
@ -226,8 +237,8 @@ var
|
||||||
begin
|
begin
|
||||||
result := nil;
|
result := nil;
|
||||||
for i := 0 to rsonsLen(n)-1 do
|
for i := 0 to rsonsLen(n)-1 do
|
||||||
appRopeFormat(result, inner, [renderRstToHtml(d, n.sons[i])]);
|
appf(result, inner, [renderRstToHtml(d, n.sons[i])]);
|
||||||
result := ropeFormat(outer, [result]);
|
result := ropef(outer, [result]);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure setIndexForSourceTerm(d: PDoc; name: PRstNode; id: int);
|
procedure setIndexForSourceTerm(d: PDoc; name: PRstNode; id: int);
|
||||||
|
|
@ -249,7 +260,7 @@ var
|
||||||
a, h: PRstNode;
|
a, h: PRstNode;
|
||||||
begin
|
begin
|
||||||
inc(d.id);
|
inc(d.id);
|
||||||
result := ropeFormat('<em id="$1">$2</em>',
|
result := ropef('<em id="$1">$2</em>',
|
||||||
[toRope(d.id), renderAux(d, n)]);
|
[toRope(d.id), renderAux(d, n)]);
|
||||||
h := newRstNode(rnHyperlink);
|
h := newRstNode(rnHyperlink);
|
||||||
a := newRstNode(rnLeaf, d.indexValFilename +{&} '#' +{&} toString(d.id));
|
a := newRstNode(rnLeaf, d.indexValFilename +{&} '#' +{&} toString(d.id));
|
||||||
|
|
@ -277,11 +288,13 @@ var
|
||||||
begin
|
begin
|
||||||
if n = nil then begin result := nil; exit end;
|
if n = nil then begin result := nil; exit end;
|
||||||
result := genComment(d, n);
|
result := genComment(d, n);
|
||||||
if result = nil then
|
if result = nil then begin
|
||||||
|
if not (n.kind in [nkEmpty..nkNilLit]) then
|
||||||
for i := 0 to sonsLen(n)-1 do begin
|
for i := 0 to sonsLen(n)-1 do begin
|
||||||
result := genRecComment(d, n.sons[i]);
|
result := genRecComment(d, n.sons[i]);
|
||||||
if result <> nil then exit
|
if result <> nil then exit
|
||||||
end
|
end
|
||||||
|
end
|
||||||
else
|
else
|
||||||
n.comment := snil
|
n.comment := snil
|
||||||
end;
|
end;
|
||||||
|
|
@ -303,14 +316,14 @@ begin
|
||||||
result := isVisible(n.sons[0]);
|
result := isVisible(n.sons[0]);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function getName(n: PNode): string;
|
function getName(n: PNode; splitAfter: int = -1): string;
|
||||||
begin
|
begin
|
||||||
case n.kind of
|
case n.kind of
|
||||||
nkPostfix: result := getName(n.sons[1]);
|
nkPostfix: result := getName(n.sons[1], splitAfter);
|
||||||
nkPragmaExpr: result := getName(n.sons[0]);
|
nkPragmaExpr: result := getName(n.sons[0], splitAfter);
|
||||||
nkSym: result := toXML(n.sym.name.s);
|
nkSym: result := toXML(n.sym.name.s, splitAfter);
|
||||||
nkIdent: result := toXML(n.ident.s);
|
nkIdent: result := toXML(n.ident.s, splitAfter);
|
||||||
nkAccQuoted: result := '`' +{&} getName(n.sons[0]) +{&} '`';
|
nkAccQuoted: result := '`' +{&} getName(n.sons[0], splitAfter) +{&} '`';
|
||||||
else begin
|
else begin
|
||||||
internalError(n.info, 'getName()');
|
internalError(n.info, 'getName()');
|
||||||
result := ''
|
result := ''
|
||||||
|
|
@ -355,38 +368,38 @@ begin
|
||||||
case kind of
|
case kind of
|
||||||
tkEof: break;
|
tkEof: break;
|
||||||
tkComment:
|
tkComment:
|
||||||
appRopeFormat(result, '<span class="Comment">$1</span>',
|
appf(result, '<span class="Comment">$1</span>',
|
||||||
[toRope(toXml(literal))]);
|
[toRope(toXml(literal))]);
|
||||||
tokKeywordLow..tokKeywordHigh:
|
tokKeywordLow..tokKeywordHigh:
|
||||||
appRopeFormat(result, '<span class="Keyword">$1</span>',
|
appf(result, '<span class="Keyword">$1</span>',
|
||||||
[toRope(literal)]);
|
[toRope(literal)]);
|
||||||
tkOpr, tkHat:
|
tkOpr, tkHat:
|
||||||
appRopeFormat(result, '<span class="Operator">$1</span>',
|
appf(result, '<span class="Operator">$1</span>',
|
||||||
[toRope(toXml(literal))]);
|
[toRope(toXml(literal))]);
|
||||||
tkStrLit..tkTripleStrLit:
|
tkStrLit..tkTripleStrLit:
|
||||||
appRopeFormat(result, '<span class="StringLit">$1</span>',
|
appf(result, '<span class="StringLit">$1</span>',
|
||||||
[toRope(toXml(literal))]);
|
[toRope(toXml(literal))]);
|
||||||
tkCharLit, tkRCharLit:
|
tkCharLit:
|
||||||
appRopeFormat(result, '<span class="CharLit">$1</span>',
|
appf(result, '<span class="CharLit">$1</span>',
|
||||||
[toRope(toXml(literal))]);
|
[toRope(toXml(literal))]);
|
||||||
tkIntLit..tkInt64Lit:
|
tkIntLit..tkInt64Lit:
|
||||||
appRopeFormat(result, '<span class="DecNumber">$1</span>',
|
appf(result, '<span class="DecNumber">$1</span>',
|
||||||
[toRope(literal)]);
|
[toRope(literal)]);
|
||||||
tkFloatLit..tkFloat64Lit:
|
tkFloatLit..tkFloat64Lit:
|
||||||
appRopeFormat(result, '<span class="FloatNumber">$1</span>',
|
appf(result, '<span class="FloatNumber">$1</span>',
|
||||||
[toRope(literal)]);
|
[toRope(literal)]);
|
||||||
tkSymbol:
|
tkSymbol:
|
||||||
appRopeFormat(result, '<span class="Identifier">$1</span>',
|
appf(result, '<span class="Identifier">$1</span>',
|
||||||
[toRope(literal)]);
|
[toRope(literal)]);
|
||||||
tkInd, tkSad, tkDed, tkSpaces:
|
tkInd, tkSad, tkDed, tkSpaces:
|
||||||
app(result, literal);
|
app(result, literal);
|
||||||
//appRopeFormat(result, '<span class="Whitespace">$1</span>',
|
//appf(result, '<span class="Whitespace">$1</span>',
|
||||||
// [toRope(literal)]);
|
// [toRope(literal)]);
|
||||||
tkParLe, tkParRi, tkBracketLe, tkBracketRi, tkCurlyLe, tkCurlyRi,
|
tkParLe, tkParRi, tkBracketLe, tkBracketRi, tkCurlyLe, tkCurlyRi,
|
||||||
tkBracketDotLe, tkBracketDotRi, tkCurlyDotLe, tkCurlyDotRi,
|
tkBracketDotLe, tkBracketDotRi, tkCurlyDotLe, tkCurlyDotRi,
|
||||||
tkParDotLe, tkParDotRi, tkComma, tkSemiColon, tkColon,
|
tkParDotLe, tkParDotRi, tkComma, tkSemiColon, tkColon,
|
||||||
tkEquals, tkDot, tkDotDot, tkAccent:
|
tkEquals, tkDot, tkDotDot, tkAccent:
|
||||||
appRopeFormat(result, '<span class="Other">$1</span>',
|
appf(result, '<span class="Other">$1</span>',
|
||||||
[toRope(literal)]);
|
[toRope(literal)]);
|
||||||
else InternalError(n.info, 'docgen.genThing(' + toktypeToStr[kind] + ')');
|
else InternalError(n.info, 'docgen.genThing(' + toktypeToStr[kind] + ')');
|
||||||
end
|
end
|
||||||
|
|
@ -397,7 +410,7 @@ begin
|
||||||
[name, result, comm, toRope(d.id)]));
|
[name, result, comm, toRope(d.id)]));
|
||||||
app(d.toc[k], ropeFormatNamedVars(getConfigVar('doc.item.toc'),
|
app(d.toc[k], ropeFormatNamedVars(getConfigVar('doc.item.toc'),
|
||||||
['name', 'header', 'desc', 'itemID'],
|
['name', 'header', 'desc', 'itemID'],
|
||||||
[name, result, comm, toRope(d.id)]));
|
[toRope(getName(nameNode, d.splitAfter)), result, comm, toRope(d.id)]));
|
||||||
setIndexForSourceTerm(d, getRstName(nameNode), d.id);
|
setIndexForSourceTerm(d, getRstName(nameNode), d.id);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
@ -416,12 +429,12 @@ begin
|
||||||
d.tocPart[len].refname := refname;
|
d.tocPart[len].refname := refname;
|
||||||
d.tocPart[len].n := n;
|
d.tocPart[len].n := n;
|
||||||
d.tocPart[len].header := result;
|
d.tocPart[len].header := result;
|
||||||
result := ropeFormat('<h$1><a class="toc-backref" id="$2" href="#$2_toc">$3'+
|
result := ropef('<h$1><a class="toc-backref" id="$2" href="#$2_toc">$3'+
|
||||||
'</a></h$1>',
|
'</a></h$1>',
|
||||||
[toRope(n.level), d.tocPart[len].refname, result]);
|
[toRope(n.level), d.tocPart[len].refname, result]);
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
result := ropeFormat('<h$1 id="$2">$3</h$1>',
|
result := ropef('<h$1 id="$2">$3</h$1>',
|
||||||
[toRope(n.level), refname, result]);
|
[toRope(n.level), refname, result]);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
@ -437,7 +450,7 @@ begin
|
||||||
if d.meta[metaTitle] = nil then d.meta[metaTitle] := t
|
if d.meta[metaTitle] = nil then d.meta[metaTitle] := t
|
||||||
else if d.meta[metaSubtitle] = nil then d.meta[metaSubtitle] := t
|
else if d.meta[metaSubtitle] = nil then d.meta[metaSubtitle] := t
|
||||||
else
|
else
|
||||||
result := ropeFormat('<h$1 id="$2"><center>$3</center></h$1>',
|
result := ropef('<h$1 id="$2"><center>$3</center></h$1>',
|
||||||
[toRope(n.level), toRope(rstnodeToRefname(n)), t]);
|
[toRope(n.level), toRope(rstnodeToRefname(n)), t]);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
@ -469,32 +482,32 @@ begin
|
||||||
rnHeadline: begin
|
rnHeadline: begin
|
||||||
result := renderRstSons(d, n);
|
result := renderRstSons(d, n);
|
||||||
L := ropeLen(result);
|
L := ropeLen(result);
|
||||||
result := ropeFormat('$n$1$2$n$1$3', [ind, result,
|
result := ropef('$n$1$2$n$1$3', [ind, result,
|
||||||
toRope(repeatChar(L, lvlToChar[n.level]))]);
|
toRope(repeatChar(L, lvlToChar[n.level]))]);
|
||||||
end;
|
end;
|
||||||
rnOverline: begin
|
rnOverline: begin
|
||||||
result := renderRstSons(d, n);
|
result := renderRstSons(d, n);
|
||||||
L := ropeLen(result);
|
L := ropeLen(result);
|
||||||
result := ropeFormat('$n$1$3$n$1$2$n$1$3', [ind, result,
|
result := ropef('$n$1$3$n$1$2$n$1$3', [ind, result,
|
||||||
toRope(repeatChar(L, lvlToChar[n.level]))]);
|
toRope(repeatChar(L, lvlToChar[n.level]))]);
|
||||||
end;
|
end;
|
||||||
rnTransition:
|
rnTransition:
|
||||||
result := ropeFormat('$n$n$1$2$n$n',
|
result := ropef('$n$n$1$2$n$n',
|
||||||
[ind, toRope(repeatChar(78-d.indent, '-'))]);
|
[ind, toRope(repeatChar(78-d.indent, '-'))]);
|
||||||
rnParagraph: begin
|
rnParagraph: begin
|
||||||
result := renderRstSons(d, n);
|
result := renderRstSons(d, n);
|
||||||
result := ropeFormat('$n$n$1$2', [ind, result]);
|
result := ropef('$n$n$1$2', [ind, result]);
|
||||||
end;
|
end;
|
||||||
rnBulletItem: begin
|
rnBulletItem: begin
|
||||||
inc(d.indent, 2);
|
inc(d.indent, 2);
|
||||||
result := renderRstSons(d, n);
|
result := renderRstSons(d, n);
|
||||||
if result <> nil then result := ropeFormat('$n$1* $2', [ind, result]);
|
if result <> nil then result := ropef('$n$1* $2', [ind, result]);
|
||||||
dec(d.indent, 2);
|
dec(d.indent, 2);
|
||||||
end;
|
end;
|
||||||
rnEnumItem: begin
|
rnEnumItem: begin
|
||||||
inc(d.indent, 4);
|
inc(d.indent, 4);
|
||||||
result := renderRstSons(d, n);
|
result := renderRstSons(d, n);
|
||||||
if result <> nil then result := ropeFormat('$n$1(#) $2', [ind, result]);
|
if result <> nil then result := ropef('$n$1(#) $2', [ind, result]);
|
||||||
dec(d.indent, 4);
|
dec(d.indent, 4);
|
||||||
end;
|
end;
|
||||||
rnOptionList, rnFieldList, rnDefList, rnDefItem, rnLineBlock, rnFieldName,
|
rnOptionList, rnFieldList, rnDefList, rnDefItem, rnLineBlock, rnFieldName,
|
||||||
|
|
@ -502,27 +515,27 @@ begin
|
||||||
result := renderRstSons(d, n);
|
result := renderRstSons(d, n);
|
||||||
rnDefName: begin
|
rnDefName: begin
|
||||||
result := renderRstSons(d, n);
|
result := renderRstSons(d, n);
|
||||||
result := ropeFormat('$n$n$1$2', [ind, result]);
|
result := ropef('$n$n$1$2', [ind, result]);
|
||||||
end;
|
end;
|
||||||
rnDefBody: begin
|
rnDefBody: begin
|
||||||
inc(d.indent, 2);
|
inc(d.indent, 2);
|
||||||
result := renderRstSons(d, n);
|
result := renderRstSons(d, n);
|
||||||
if n.sons[0].kind <> rnBulletList then
|
if n.sons[0].kind <> rnBulletList then
|
||||||
result := ropeFormat('$n$1 $2', [ind, result]);
|
result := ropef('$n$1 $2', [ind, result]);
|
||||||
dec(d.indent, 2);
|
dec(d.indent, 2);
|
||||||
end;
|
end;
|
||||||
rnField: begin
|
rnField: begin
|
||||||
result := renderRstToRst(d, n.sons[0]);
|
result := renderRstToRst(d, n.sons[0]);
|
||||||
L := max(ropeLen(result)+3, 30);
|
L := max(ropeLen(result)+3, 30);
|
||||||
inc(d.indent, L);
|
inc(d.indent, L);
|
||||||
result := ropeFormat('$n$1:$2:$3$4', [
|
result := ropef('$n$1:$2:$3$4', [
|
||||||
ind, result, toRope(repeatChar(L-ropeLen(result)-2)),
|
ind, result, toRope(repeatChar(L-ropeLen(result)-2)),
|
||||||
renderRstToRst(d, n.sons[1])]);
|
renderRstToRst(d, n.sons[1])]);
|
||||||
dec(d.indent, L);
|
dec(d.indent, L);
|
||||||
end;
|
end;
|
||||||
rnLineBlockItem: begin
|
rnLineBlockItem: begin
|
||||||
result := renderRstSons(d, n);
|
result := renderRstSons(d, n);
|
||||||
result := ropeFormat('$n$1| $2', [ind, result]);
|
result := ropef('$n$1| $2', [ind, result]);
|
||||||
end;
|
end;
|
||||||
rnBlockQuote: begin
|
rnBlockQuote: begin
|
||||||
inc(d.indent, 2);
|
inc(d.indent, 2);
|
||||||
|
|
@ -531,44 +544,44 @@ begin
|
||||||
end;
|
end;
|
||||||
rnRef: begin
|
rnRef: begin
|
||||||
result := renderRstSons(d, n);
|
result := renderRstSons(d, n);
|
||||||
result := ropeFormat('`$1`_', [result]);
|
result := ropef('`$1`_', [result]);
|
||||||
end;
|
end;
|
||||||
rnHyperlink: begin
|
rnHyperlink: begin
|
||||||
result := ropeFormat('`$1 <$2>`_', [renderRstToRst(d, n.sons[0]),
|
result := ropef('`$1 <$2>`_', [renderRstToRst(d, n.sons[0]),
|
||||||
renderRstToRst(d, n.sons[1])]);
|
renderRstToRst(d, n.sons[1])]);
|
||||||
end;
|
end;
|
||||||
rnGeneralRole: begin
|
rnGeneralRole: begin
|
||||||
result := renderRstToRst(d, n.sons[0]);
|
result := renderRstToRst(d, n.sons[0]);
|
||||||
result := ropeFormat('`$1`:$2:', [result, renderRstToRst(d, n.sons[1])]);
|
result := ropef('`$1`:$2:', [result, renderRstToRst(d, n.sons[1])]);
|
||||||
end;
|
end;
|
||||||
rnSub: begin
|
rnSub: begin
|
||||||
result := renderRstSons(d, n);
|
result := renderRstSons(d, n);
|
||||||
result := ropeFormat('`$1`:sub:', [result]);
|
result := ropef('`$1`:sub:', [result]);
|
||||||
end;
|
end;
|
||||||
rnSup: begin
|
rnSup: begin
|
||||||
result := renderRstSons(d, n);
|
result := renderRstSons(d, n);
|
||||||
result := ropeFormat('`$1`:sup:', [result]);
|
result := ropef('`$1`:sup:', [result]);
|
||||||
end;
|
end;
|
||||||
rnIdx: begin
|
rnIdx: begin
|
||||||
result := renderRstSons(d, n);
|
result := renderRstSons(d, n);
|
||||||
result := ropeFormat('`$1`:idx:', [result]);
|
result := ropef('`$1`:idx:', [result]);
|
||||||
end;
|
end;
|
||||||
rnEmphasis: begin
|
rnEmphasis: begin
|
||||||
result := renderRstSons(d, n);
|
result := renderRstSons(d, n);
|
||||||
result := ropeFormat('*$1*', [result]);
|
result := ropef('*$1*', [result]);
|
||||||
end;
|
end;
|
||||||
rnStrongEmphasis: begin
|
rnStrongEmphasis: begin
|
||||||
result := renderRstSons(d, n);
|
result := renderRstSons(d, n);
|
||||||
result := ropeFormat('**$1**', [result]);
|
result := ropef('**$1**', [result]);
|
||||||
end;
|
end;
|
||||||
rnInterpretedText: begin
|
rnInterpretedText: begin
|
||||||
result := renderRstSons(d, n);
|
result := renderRstSons(d, n);
|
||||||
result := ropeFormat('`$1`', [result]);
|
result := ropef('`$1`', [result]);
|
||||||
end;
|
end;
|
||||||
rnInlineLiteral: begin
|
rnInlineLiteral: begin
|
||||||
inc(d.verbatim);
|
inc(d.verbatim);
|
||||||
result := renderRstSons(d, n);
|
result := renderRstSons(d, n);
|
||||||
result := ropeFormat('``$1``', [result]);
|
result := ropef('``$1``', [result]);
|
||||||
dec(d.verbatim);
|
dec(d.verbatim);
|
||||||
end;
|
end;
|
||||||
rnLeaf: begin
|
rnLeaf: begin
|
||||||
|
|
@ -582,10 +595,10 @@ begin
|
||||||
if n.sons[2] <> nil then
|
if n.sons[2] <> nil then
|
||||||
result := renderRstSons(d, n.sons[2]);
|
result := renderRstSons(d, n.sons[2]);
|
||||||
dec(d.indent, 3);
|
dec(d.indent, 3);
|
||||||
result := ropeFormat('$n$n$1.. index::$n$2', [ind, result]);
|
result := ropef('$n$n$1.. index::$n$2', [ind, result]);
|
||||||
end;
|
end;
|
||||||
rnContents: begin
|
rnContents: begin
|
||||||
result := ropeFormat('$n$n$1.. contents::', [ind]);
|
result := ropef('$n$n$1.. contents::', [ind]);
|
||||||
end;
|
end;
|
||||||
else rawMessage(errCannotRenderX, rstnodeKindToStr[n.kind]);
|
else rawMessage(errCannotRenderX, rstnodeKindToStr[n.kind]);
|
||||||
end;
|
end;
|
||||||
|
|
@ -593,7 +606,7 @@ end;
|
||||||
|
|
||||||
function renderTocEntry(d: PDoc; const e: TTocEntry): PRope;
|
function renderTocEntry(d: PDoc; const e: TTocEntry): PRope;
|
||||||
begin
|
begin
|
||||||
result := ropeFormat('<li><a class="reference" id="$1_toc" href="#$1">$2' +
|
result := ropef('<li><a class="reference" id="$1_toc" href="#$1">$2' +
|
||||||
'</a></li>$n', [e.refname, e.header]);
|
'</a></li>$n', [e.refname, e.header]);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
@ -614,24 +627,24 @@ begin
|
||||||
break
|
break
|
||||||
end;
|
end;
|
||||||
if lvl > 1 then
|
if lvl > 1 then
|
||||||
result := ropeFormat('<ul class="simple">$1</ul>', [result]);
|
result := ropef('<ul class="simple">$1</ul>', [result]);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function renderImage(d: PDoc; n: PRstNode): PRope;
|
function renderImage(d: PDoc; n: PRstNode): PRope;
|
||||||
var
|
var
|
||||||
s: string;
|
s: string;
|
||||||
begin
|
begin
|
||||||
result := ropeFormat('<img src="$1"', [toRope(getArgument(n))]);
|
result := ropef('<img src="$1"', [toRope(getArgument(n))]);
|
||||||
s := getFieldValue(n, 'height');
|
s := getFieldValue(n, 'height');
|
||||||
if s <> '' then appRopeFormat(result, ' height="$1"', [toRope(s)]);
|
if s <> '' then appf(result, ' height="$1"', [toRope(s)]);
|
||||||
s := getFieldValue(n, 'width');
|
s := getFieldValue(n, 'width');
|
||||||
if s <> '' then appRopeFormat(result, ' width="$1"', [toRope(s)]);
|
if s <> '' then appf(result, ' width="$1"', [toRope(s)]);
|
||||||
s := getFieldValue(n, 'scale');
|
s := getFieldValue(n, 'scale');
|
||||||
if s <> '' then appRopeFormat(result, ' scale="$1"', [toRope(s)]);
|
if s <> '' then appf(result, ' scale="$1"', [toRope(s)]);
|
||||||
s := getFieldValue(n, 'alt');
|
s := getFieldValue(n, 'alt');
|
||||||
if s <> '' then appRopeFormat(result, ' alt="$1"', [toRope(s)]);
|
if s <> '' then appf(result, ' alt="$1"', [toRope(s)]);
|
||||||
s := getFieldValue(n, 'align');
|
s := getFieldValue(n, 'align');
|
||||||
if s <> '' then appRopeFormat(result, ' align="$1"', [toRope(s)]);
|
if s <> '' then appf(result, ' align="$1"', [toRope(s)]);
|
||||||
app(result, ' />');
|
app(result, ' />');
|
||||||
if rsonsLen(n) >= 3 then app(result, renderRstToHtml(d, n.sons[2]))
|
if rsonsLen(n) >= 3 then app(result, renderRstToHtml(d, n.sons[2]))
|
||||||
end;
|
end;
|
||||||
|
|
@ -644,14 +657,14 @@ var
|
||||||
lang: TSourceLanguage;
|
lang: TSourceLanguage;
|
||||||
begin
|
begin
|
||||||
m := n.sons[2].sons[0];
|
m := n.sons[2].sons[0];
|
||||||
assert(m.kind = rnLeaf);
|
if (m.kind <> rnLeaf) then InternalError('renderCodeBlock');
|
||||||
result := nil;
|
result := nil;
|
||||||
langstr := strip(getArgument(n));
|
langstr := strip(getArgument(n));
|
||||||
if langstr = '' then lang := langNimrod // default language
|
if langstr = '' then lang := langNimrod // default language
|
||||||
else lang := getSourceLanguage(langstr);
|
else lang := getSourceLanguage(langstr);
|
||||||
if lang = langNone then begin
|
if lang = langNone then begin
|
||||||
rawMessage(warnLanguageXNotSupported, langstr);
|
rawMessage(warnLanguageXNotSupported, langstr);
|
||||||
result := ropeFormat('<pre>$1</pre>', [toRope(m.text)])
|
result := ropef('<pre>$1</pre>', [toRope(m.text)])
|
||||||
end
|
end
|
||||||
else begin
|
else begin
|
||||||
initGeneralTokenizer(g, m.text);
|
initGeneralTokenizer(g, m.text);
|
||||||
|
|
@ -660,15 +673,17 @@ begin
|
||||||
case g.kind of
|
case g.kind of
|
||||||
gtEof: break;
|
gtEof: break;
|
||||||
gtNone, gtWhitespace:
|
gtNone, gtWhitespace:
|
||||||
app(result, ncopy(m.text, g.start+strStart, g.len+g.start));
|
app(result, ncopy(m.text, g.start+strStart,
|
||||||
|
g.len+g.start-1+strStart));
|
||||||
else
|
else
|
||||||
appRopeFormat(result, '<span class="$2">$1</span>',
|
appf(result, '<span class="$2">$1</span>',
|
||||||
[toRope(ncopy(m.text, g.start+strStart, g.len+g.start)),
|
[toRope(ncopy(m.text, g.start+strStart,
|
||||||
|
g.len+g.start-1+strStart)),
|
||||||
toRope(tokenClassToStr[g.kind])]);
|
toRope(tokenClassToStr[g.kind])]);
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
deinitGeneralTokenizer(g);
|
deinitGeneralTokenizer(g);
|
||||||
if result <> nil then result := ropeFormat('<pre>$1</pre>', [result]);
|
if result <> nil then result := ropef('<pre>$1</pre>', [result]);
|
||||||
end
|
end
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
@ -719,10 +734,10 @@ begin
|
||||||
rnDescription: outer := '<td align="left">$1</td>$n';
|
rnDescription: outer := '<td align="left">$1</td>$n';
|
||||||
rnOption,
|
rnOption,
|
||||||
rnOptionString,
|
rnOptionString,
|
||||||
rnOptionArgument: assert(false);
|
rnOptionArgument: InternalError('renderRstToHtml');
|
||||||
|
|
||||||
rnLiteralBlock: outer := '<pre>$1</pre>'+nl;
|
rnLiteralBlock: outer := '<pre>$1</pre>'+nl;
|
||||||
rnQuotedLiteralBlock: assert(false);
|
rnQuotedLiteralBlock: InternalError('renderRstToHtml');
|
||||||
|
|
||||||
rnLineBlock: outer := '<p>$1</p>';
|
rnLineBlock: outer := '<p>$1</p>';
|
||||||
rnLineBlockItem: outer := '$1<br />';
|
rnLineBlockItem: outer := '$1<br />';
|
||||||
|
|
@ -735,19 +750,19 @@ begin
|
||||||
rnTableDataCell: outer := '<td>$1</td>';
|
rnTableDataCell: outer := '<td>$1</td>';
|
||||||
rnTableHeaderCell: outer := '<th>$1</th>';
|
rnTableHeaderCell: outer := '<th>$1</th>';
|
||||||
|
|
||||||
rnLabel: assert(false); // used for footnotes and other things
|
rnLabel: InternalError('renderRstToHtml'); // used for footnotes and other
|
||||||
rnFootnote: assert(false); // a footnote
|
rnFootnote: InternalError('renderRstToHtml'); // a footnote
|
||||||
|
|
||||||
rnCitation: assert(false); // similar to footnote
|
rnCitation: InternalError('renderRstToHtml'); // similar to footnote
|
||||||
rnRef: begin
|
rnRef: begin
|
||||||
result := ropeFormat('<a class="reference external" href="#$2">$1</a>',
|
result := ropef('<a class="reference external" href="#$2">$1</a>',
|
||||||
[renderAux(d, n), toRope(rstnodeToRefname(n))]);
|
[renderAux(d, n), toRope(rstnodeToRefname(n))]);
|
||||||
exit
|
exit
|
||||||
end;
|
end;
|
||||||
rnStandaloneHyperlink:
|
rnStandaloneHyperlink:
|
||||||
outer := '<a class="reference external" href="$1">$1</a>';
|
outer := '<a class="reference external" href="$1">$1</a>';
|
||||||
rnHyperlink: begin
|
rnHyperlink: begin
|
||||||
result := ropeFormat('<a class="reference external" href="$2">$1</a>',
|
result := ropef('<a class="reference external" href="$2">$1</a>',
|
||||||
[renderRstToHtml(d, n.sons[0]),
|
[renderRstToHtml(d, n.sons[0]),
|
||||||
renderRstToHtml(d, n.sons[1])]);
|
renderRstToHtml(d, n.sons[1])]);
|
||||||
exit
|
exit
|
||||||
|
|
@ -766,7 +781,7 @@ begin
|
||||||
|
|
||||||
// Inline markup:
|
// Inline markup:
|
||||||
rnGeneralRole: begin
|
rnGeneralRole: begin
|
||||||
result := ropeFormat('<span class="$2">$1</span>',
|
result := ropef('<span class="$2">$1</span>',
|
||||||
[renderRstToHtml(d, n.sons[0]),
|
[renderRstToHtml(d, n.sons[0]),
|
||||||
renderRstToHtml(d, n.sons[1])]);
|
renderRstToHtml(d, n.sons[1])]);
|
||||||
exit
|
exit
|
||||||
|
|
@ -798,7 +813,7 @@ begin
|
||||||
d.meta[metaTitle] := renderRstToHtml(d, n.sons[0]);
|
d.meta[metaTitle] := renderRstToHtml(d, n.sons[0]);
|
||||||
exit
|
exit
|
||||||
end;
|
end;
|
||||||
else assert(false);
|
else InternalError('renderRstToHtml');
|
||||||
end;
|
end;
|
||||||
result := renderAux(d, n, outer, inner);
|
result := renderAux(d, n, outer, inner);
|
||||||
end;
|
end;
|
||||||
|
|
@ -814,6 +829,7 @@ begin
|
||||||
nkIteratorDef: genItem(d, n, n.sons[namePos], skIterator);
|
nkIteratorDef: genItem(d, n, n.sons[namePos], skIterator);
|
||||||
nkMacroDef: genItem(d, n, n.sons[namePos], skMacro);
|
nkMacroDef: genItem(d, n, n.sons[namePos], skMacro);
|
||||||
nkTemplateDef: genItem(d, n, n.sons[namePos], skTemplate);
|
nkTemplateDef: genItem(d, n, n.sons[namePos], skTemplate);
|
||||||
|
nkConverterDef: genItem(d, n, n.sons[namePos], skConverter);
|
||||||
nkVarSection: begin
|
nkVarSection: begin
|
||||||
for i := 0 to sonsLen(n)-1 do
|
for i := 0 to sonsLen(n)-1 do
|
||||||
genItem(d, n.sons[i], n.sons[i].sons[0], skVar);
|
genItem(d, n.sons[i], n.sons[i].sons[0], skVar);
|
||||||
|
|
@ -860,13 +876,15 @@ var
|
||||||
begin
|
begin
|
||||||
j := 0;
|
j := 0;
|
||||||
toc := renderTocEntries(d, j, 1);
|
toc := renderTocEntries(d, j, 1);
|
||||||
|
code := nil;
|
||||||
|
content := nil;
|
||||||
|
title := nil;
|
||||||
for i := low(TSymKind) to high(TSymKind) do begin
|
for i := low(TSymKind) to high(TSymKind) do begin
|
||||||
genSection(d, i);
|
genSection(d, i);
|
||||||
app(toc, d.toc[i]);
|
app(toc, d.toc[i]);
|
||||||
end;
|
end;
|
||||||
if toc <> nil then
|
if toc <> nil then
|
||||||
toc := ropeFormatNamedVars(getConfigVar('doc.toc'), ['content'], [toc]);
|
toc := ropeFormatNamedVars(getConfigVar('doc.toc'), ['content'], [toc]);
|
||||||
code := nil;
|
|
||||||
for i := low(TSymKind) to high(TSymKind) do
|
for i := low(TSymKind) to high(TSymKind) do
|
||||||
app(code, d.section[i]);
|
app(code, d.section[i]);
|
||||||
if d.meta[metaTitle] <> nil then
|
if d.meta[metaTitle] <> nil then
|
||||||
|
|
@ -918,13 +936,16 @@ var
|
||||||
filen: string;
|
filen: string;
|
||||||
d: PDoc;
|
d: PDoc;
|
||||||
rst: PRstNode;
|
rst: PRstNode;
|
||||||
|
code: PRope;
|
||||||
begin
|
begin
|
||||||
filen := appendFileExt(filename, 'txt');
|
filen := appendFileExt(filename, 'txt');
|
||||||
d := newDocumentor(filen);
|
d := newDocumentor(filen);
|
||||||
initIndexFile(d);
|
initIndexFile(d);
|
||||||
rst := rstParse(readFile(filen), false, filen, 0, 1, d.hasToc);
|
rst := rstParse(readFile(filen), false, filen, 0, 1, d.hasToc);
|
||||||
d.modDesc := renderRstToHtml(d, rst);
|
d.modDesc := renderRstToHtml(d, rst);
|
||||||
writeRope(genHtmlFile(d), getOutFile(filename, HtmlExt));
|
code := genHtmlFile(d);
|
||||||
|
assert(ropeInvariant(code));
|
||||||
|
writeRope(code, getOutFile(filename, HtmlExt));
|
||||||
generateIndex(d);
|
generateIndex(d);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
|
||||||
1869
nim/ecmasgen.pas
Normal file
1869
nim/ecmasgen.pas
Normal file
File diff suppressed because it is too large
Load diff
1242
nim/eval.pas
1242
nim/eval.pas
File diff suppressed because it is too large
Load diff
138
nim/extccomp.pas
138
nim/extccomp.pas
|
|
@ -15,7 +15,9 @@ interface
|
||||||
{$include 'config.inc'}
|
{$include 'config.inc'}
|
||||||
|
|
||||||
uses
|
uses
|
||||||
nimconf, msgs; // some things are read in from the configuration file
|
nsystem, nimconf, msgs;
|
||||||
|
|
||||||
|
// some things are read in from the configuration file
|
||||||
|
|
||||||
type
|
type
|
||||||
TSystemCC = (ccNone, ccGcc, ccLLVM_Gcc, ccLcc, ccBcc, ccDmc, ccWcc, ccVcc,
|
TSystemCC = (ccNone, ccGcc, ccLLVM_Gcc, ccLcc, ccBcc, ccDmc, ccWcc, ccVcc,
|
||||||
|
|
@ -27,15 +29,17 @@ type
|
||||||
hasCpp // CC is/contains a C++ compiler
|
hasCpp // CC is/contains a C++ compiler
|
||||||
);
|
);
|
||||||
TInfoCCProps = set of TInfoCCProp;
|
TInfoCCProps = set of TInfoCCProp;
|
||||||
TInfoCC = record
|
TInfoCC = record{@tuple}
|
||||||
name: string; // the short name of the compiler
|
name: string; // the short name of the compiler
|
||||||
objExt: string; // the compiler's object file extenstion
|
objExt: string; // the compiler's object file extenstion
|
||||||
optSpeed: string; // the options for optimization for speed
|
optSpeed: string; // the options for optimization for speed
|
||||||
optSize: string; // the options for optimization for size
|
optSize: string; // the options for optimization for size
|
||||||
compile: string; // the compile command template
|
compilerExe: string; // the compiler's executable
|
||||||
|
compileTmpl: string; // the compile command template
|
||||||
buildGui: string; // command to build a GUI application
|
buildGui: string; // command to build a GUI application
|
||||||
buildDll: string; // command to build a shared library
|
buildDll: string; // command to build a shared library
|
||||||
link: string; // command to link files to produce an executable
|
linkerExe: string; // the linker's executable
|
||||||
|
linkTmpl: string; // command to link files to produce an executable
|
||||||
includeCmd: string; // command to add an include directory path
|
includeCmd: string; // command to add an include directory path
|
||||||
debug: string; // flags for debug build
|
debug: string; // flags for debug build
|
||||||
pic: string; // command for position independent code
|
pic: string; // command for position independent code
|
||||||
|
|
@ -50,10 +54,12 @@ const
|
||||||
objExt: 'o'+'';
|
objExt: 'o'+'';
|
||||||
optSpeed: ' -O3 -ffast-math ';
|
optSpeed: ' -O3 -ffast-math ';
|
||||||
optSize: ' -Os -ffast-math ';
|
optSize: ' -Os -ffast-math ';
|
||||||
compile: 'gcc -c $options $include -o $objfile $file';
|
compilerExe: 'gcc';
|
||||||
|
compileTmpl: '-c $options $include -o $objfile $file';
|
||||||
buildGui: ' -mwindows';
|
buildGui: ' -mwindows';
|
||||||
buildDll: ' -mdll';
|
buildDll: ' -mdll';
|
||||||
link: 'gcc $options $buildgui $builddll -o $exefile $objfiles';
|
linkerExe: 'gcc';
|
||||||
|
linkTmpl: '$options $buildgui $builddll -o $exefile $objfiles';
|
||||||
includeCmd: ' -I';
|
includeCmd: ' -I';
|
||||||
debug: '';
|
debug: '';
|
||||||
pic: '-fPIC';
|
pic: '-fPIC';
|
||||||
|
|
@ -65,10 +71,12 @@ const
|
||||||
objExt: 'o'+'';
|
objExt: 'o'+'';
|
||||||
optSpeed: ' -O3 -ffast-math ';
|
optSpeed: ' -O3 -ffast-math ';
|
||||||
optSize: ' -Os -ffast-math ';
|
optSize: ' -Os -ffast-math ';
|
||||||
compile: 'llvm-gcc -c $options $include -o $objfile $file';
|
compilerExe: 'llvm-gcc';
|
||||||
|
compileTmpl: '-c $options $include -o $objfile $file';
|
||||||
buildGui: ' -mwindows';
|
buildGui: ' -mwindows';
|
||||||
buildDll: ' -mdll';
|
buildDll: ' -mdll';
|
||||||
link: 'llvm-gcc $options $buildgui $builddll -o $exefile $objfiles';
|
linkerExe: 'llvm-gcc';
|
||||||
|
linkTmpl: '$options $buildgui $builddll -o $exefile $objfiles';
|
||||||
includeCmd: ' -I';
|
includeCmd: ' -I';
|
||||||
debug: '';
|
debug: '';
|
||||||
pic: '-fPIC';
|
pic: '-fPIC';
|
||||||
|
|
@ -80,10 +88,12 @@ const
|
||||||
objExt: 'obj';
|
objExt: 'obj';
|
||||||
optSpeed: ' -O -p6 ';
|
optSpeed: ' -O -p6 ';
|
||||||
optSize: ' -O -p6 ';
|
optSize: ' -O -p6 ';
|
||||||
compile: 'lcc -e1 $options $include -Fo$objfile $file';
|
compilerExe: 'lcc';
|
||||||
|
compileTmpl: '-e1 $options $include -Fo$objfile $file';
|
||||||
buildGui: ' -subsystem windows';
|
buildGui: ' -subsystem windows';
|
||||||
buildDll: ' -dll';
|
buildDll: ' -dll';
|
||||||
link: 'lcclnk $options $buildgui $builddll -O $exefile $objfiles';
|
linkerExe: 'lcclnk';
|
||||||
|
linkTmpl: '$options $buildgui $builddll -O $exefile $objfiles';
|
||||||
includeCmd: ' -I';
|
includeCmd: ' -I';
|
||||||
debug: ' -g5 ';
|
debug: ' -g5 ';
|
||||||
pic: '';
|
pic: '';
|
||||||
|
|
@ -95,10 +105,12 @@ const
|
||||||
objExt: 'obj';
|
objExt: 'obj';
|
||||||
optSpeed: ' -O2 -6 ';
|
optSpeed: ' -O2 -6 ';
|
||||||
optSize: ' -O1 -6 ';
|
optSize: ' -O1 -6 ';
|
||||||
compile: 'bcc32 -c $options $include -o$objfile $file';
|
compilerExe: 'bcc32';
|
||||||
|
compileTmpl: '-c $options $include -o$objfile $file';
|
||||||
buildGui: ' -tW';
|
buildGui: ' -tW';
|
||||||
buildDll: ' -tWD';
|
buildDll: ' -tWD';
|
||||||
link: 'bcc32 $options $buildgui $builddll -e$exefile $objfiles';
|
linkerExe: 'bcc32';
|
||||||
|
linkTmpl: '$options $buildgui $builddll -e$exefile $objfiles';
|
||||||
includeCmd: ' -I';
|
includeCmd: ' -I';
|
||||||
debug: '';
|
debug: '';
|
||||||
pic: '';
|
pic: '';
|
||||||
|
|
@ -110,10 +122,12 @@ const
|
||||||
objExt: 'obj';
|
objExt: 'obj';
|
||||||
optSpeed: ' -ff -o -6 ';
|
optSpeed: ' -ff -o -6 ';
|
||||||
optSize: ' -ff -o -6 ';
|
optSize: ' -ff -o -6 ';
|
||||||
compile: 'dmc -c $options $include -o$objfile $file';
|
compilerExe: 'dmc';
|
||||||
|
compileTmpl: '-c $options $include -o$objfile $file';
|
||||||
buildGui: ' -L/exet:nt/su:windows';
|
buildGui: ' -L/exet:nt/su:windows';
|
||||||
buildDll: ' -WD';
|
buildDll: ' -WD';
|
||||||
link: 'dmc $options $buildgui $builddll -o$exefile $objfiles';
|
linkerExe: 'dmc';
|
||||||
|
linkTmpl: '$options $buildgui $builddll -o$exefile $objfiles';
|
||||||
includeCmd: ' -I';
|
includeCmd: ' -I';
|
||||||
debug: ' -g ';
|
debug: ' -g ';
|
||||||
pic: '';
|
pic: '';
|
||||||
|
|
@ -125,10 +139,12 @@ const
|
||||||
objExt: 'obj';
|
objExt: 'obj';
|
||||||
optSpeed: ' -ox -on -6 -d0 -fp6 -zW ';
|
optSpeed: ' -ox -on -6 -d0 -fp6 -zW ';
|
||||||
optSize: '';
|
optSize: '';
|
||||||
compile: 'wcl386 -c $options $include -fo=$objfile $file';
|
compilerExe: 'wcl386';
|
||||||
|
compileTmpl: '-c $options $include -fo=$objfile $file';
|
||||||
buildGui: ' -bw';
|
buildGui: ' -bw';
|
||||||
buildDll: ' -bd';
|
buildDll: ' -bd';
|
||||||
link: 'wcl386 $options $buildgui $builddll -fe=$exefile $objfiles ';
|
linkerExe: 'wcl386';
|
||||||
|
linkTmpl: '$options $buildgui $builddll -fe=$exefile $objfiles ';
|
||||||
includeCmd: ' -i=';
|
includeCmd: ' -i=';
|
||||||
debug: ' -d2 ';
|
debug: ' -d2 ';
|
||||||
pic: '';
|
pic: '';
|
||||||
|
|
@ -140,10 +156,12 @@ const
|
||||||
objExt: 'obj';
|
objExt: 'obj';
|
||||||
optSpeed: ' /Ogityb2 /G7 /arch:SSE2 ';
|
optSpeed: ' /Ogityb2 /G7 /arch:SSE2 ';
|
||||||
optSize: ' /O1 /G7 ';
|
optSize: ' /O1 /G7 ';
|
||||||
compile: 'cl /c $options $include /Fo$objfile $file';
|
compilerExe: 'cl';
|
||||||
|
compileTmpl: '/c $options $include /Fo$objfile $file';
|
||||||
buildGui: ' /link /SUBSYSTEM:WINDOWS ';
|
buildGui: ' /link /SUBSYSTEM:WINDOWS ';
|
||||||
buildDll: ' /LD';
|
buildDll: ' /LD';
|
||||||
link: 'cl $options $builddll /Fe$exefile $objfiles $buildgui';
|
linkerExe: 'cl';
|
||||||
|
linkTmpl: '$options $builddll /Fe$exefile $objfiles $buildgui';
|
||||||
includeCmd: ' /I';
|
includeCmd: ' /I';
|
||||||
debug: ' /GZ /Zi ';
|
debug: ' /GZ /Zi ';
|
||||||
pic: '';
|
pic: '';
|
||||||
|
|
@ -155,10 +173,12 @@ const
|
||||||
objExt: 'o'+'';
|
objExt: 'o'+'';
|
||||||
optSpeed: '';
|
optSpeed: '';
|
||||||
optSize: '';
|
optSize: '';
|
||||||
compile: 'tcc -c $options $include -o $objfile $file';
|
compilerExe: 'tcc';
|
||||||
|
compileTmpl: '-c $options $include -o $objfile $file';
|
||||||
buildGui: 'UNAVAILABLE!';
|
buildGui: 'UNAVAILABLE!';
|
||||||
buildDll: ' -shared';
|
buildDll: ' -shared';
|
||||||
link: 'tcc -o $exefile $options $buildgui $builddll $objfiles';
|
linkerExe: 'tcc';
|
||||||
|
linkTmpl: '-o $exefile $options $buildgui $builddll $objfiles';
|
||||||
includeCmd: ' -I';
|
includeCmd: ' -I';
|
||||||
debug: ' -g ';
|
debug: ' -g ';
|
||||||
pic: '';
|
pic: '';
|
||||||
|
|
@ -170,10 +190,12 @@ const
|
||||||
objExt: 'obj';
|
objExt: 'obj';
|
||||||
optSpeed: ' -Ox ';
|
optSpeed: ' -Ox ';
|
||||||
optSize: ' -Os ';
|
optSize: ' -Os ';
|
||||||
compile: 'cc -c $options $include -Fo$objfile $file';
|
compilerExe: 'cc';
|
||||||
|
compileTmpl: '-c $options $include -Fo$objfile $file';
|
||||||
buildGui: ' -SUBSYSTEM:WINDOWS';
|
buildGui: ' -SUBSYSTEM:WINDOWS';
|
||||||
buildDll: ' -DLL';
|
buildDll: ' -DLL';
|
||||||
link: 'cc $options $buildgui $builddll -OUT:$exefile $objfiles';
|
linkerExe: 'cc';
|
||||||
|
linkTmpl: '$options $buildgui $builddll -OUT:$exefile $objfiles';
|
||||||
includeCmd: ' -I';
|
includeCmd: ' -I';
|
||||||
debug: ' -Zi ';
|
debug: ' -Zi ';
|
||||||
pic: '';
|
pic: '';
|
||||||
|
|
@ -185,10 +207,12 @@ const
|
||||||
objExt: 'o'+'';
|
objExt: 'o'+'';
|
||||||
optSpeed: ' -O3 ';
|
optSpeed: ' -O3 ';
|
||||||
optSize: ' -O1 ';
|
optSize: ' -O1 ';
|
||||||
compile: 'cc -c $options $include -o $objfile $file';
|
compilerExe: 'cc';
|
||||||
|
compileTmpl: '-c $options $include -o $objfile $file';
|
||||||
buildGui: '';
|
buildGui: '';
|
||||||
buildDll: ' -shared ';
|
buildDll: ' -shared ';
|
||||||
link: 'cc -o $exefile $options $buildgui $builddll $objfiles';
|
linkerExe: 'cc';
|
||||||
|
linkTmpl: '-o $exefile $options $buildgui $builddll $objfiles';
|
||||||
includeCmd: ' -I';
|
includeCmd: ' -I';
|
||||||
debug: '';
|
debug: '';
|
||||||
pic: '';
|
pic: '';
|
||||||
|
|
@ -199,10 +223,12 @@ const
|
||||||
objExt: 'o'+'';
|
objExt: 'o'+'';
|
||||||
optSpeed: ' -O3 ';
|
optSpeed: ' -O3 ';
|
||||||
optSize: ' -Os ';
|
optSize: ' -Os ';
|
||||||
compile: 'icc -c $options $include -o $objfile $file';
|
compilerExe: 'icc';
|
||||||
|
compileTmpl: '-c $options $include -o $objfile $file';
|
||||||
buildGui: ' -mwindows';
|
buildGui: ' -mwindows';
|
||||||
buildDll: ' -mdll';
|
buildDll: ' -mdll';
|
||||||
link: 'icc $options $buildgui $builddll -o $exefile $objfiles';
|
linkerExe: 'icc';
|
||||||
|
linkTmpl: '$options $buildgui $builddll -o $exefile $objfiles';
|
||||||
includeCmd: ' -I';
|
includeCmd: ' -I';
|
||||||
debug: '';
|
debug: '';
|
||||||
pic: '-fPIC';
|
pic: '-fPIC';
|
||||||
|
|
@ -213,10 +239,12 @@ const
|
||||||
objExt: 'o'+'';
|
objExt: 'o'+'';
|
||||||
optSpeed: ' -O3 -ffast-math ';
|
optSpeed: ' -O3 -ffast-math ';
|
||||||
optSize: ' -Os -ffast-math ';
|
optSize: ' -Os -ffast-math ';
|
||||||
compile: 'g++ -c $options $include -o $objfile $file';
|
compilerExe: 'g++';
|
||||||
|
compileTmpl: '-c $options $include -o $objfile $file';
|
||||||
buildGui: ' -mwindows';
|
buildGui: ' -mwindows';
|
||||||
buildDll: ' -mdll';
|
buildDll: ' -mdll';
|
||||||
link: 'g++ $options $buildgui $builddll -o $exefile $objfiles';
|
linkerExe: 'g++';
|
||||||
|
linkTmpl: '$options $buildgui $builddll -o $exefile $objfiles';
|
||||||
includeCmd: ' -I';
|
includeCmd: ' -I';
|
||||||
debug: ' -g ';
|
debug: ' -g ';
|
||||||
pic: '-fPIC';
|
pic: '-fPIC';
|
||||||
|
|
@ -238,6 +266,9 @@ var
|
||||||
function completeCFilePath(const cfile: string;
|
function completeCFilePath(const cfile: string;
|
||||||
createSubDir: Boolean = true): string;
|
createSubDir: Boolean = true): string;
|
||||||
|
|
||||||
|
function getCompileCFileCmd(const cfilename: string;
|
||||||
|
isExternal: bool = false): string;
|
||||||
|
|
||||||
procedure addFileToCompile(const filename: string);
|
procedure addFileToCompile(const filename: string);
|
||||||
procedure addExternalFileToCompile(const filename: string);
|
procedure addExternalFileToCompile(const filename: string);
|
||||||
procedure addFileToLink(const filename: string);
|
procedure addFileToLink(const filename: string);
|
||||||
|
|
@ -260,7 +291,7 @@ procedure setCC(const ccname: string);
|
||||||
implementation
|
implementation
|
||||||
|
|
||||||
uses
|
uses
|
||||||
nsystem, charsets,
|
charsets,
|
||||||
lists, options, ropes, nos, strutils, platform, condsyms;
|
lists, options, ropes, nos, strutils, platform, condsyms;
|
||||||
|
|
||||||
var
|
var
|
||||||
|
|
@ -389,16 +420,13 @@ begin
|
||||||
result := cc[c].optSize // use default settings from this file
|
result := cc[c].optSize // use default settings from this file
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure CompileCFile(const list: TLinkedList;
|
function getCompileCFileCmd(const cfilename: string;
|
||||||
var script: PRope; isExternal: Boolean);
|
isExternal: bool = false): string;
|
||||||
var
|
var
|
||||||
it: PStrEntry;
|
cfile, objfile, options, includeCmd, compilePattern: string;
|
||||||
compileCmd, cfile, objfile, options, includeCmd, compilePattern: string;
|
|
||||||
c: TSystemCC; // an alias to ccompiler
|
c: TSystemCC; // an alias to ccompiler
|
||||||
begin
|
begin
|
||||||
c := ccompiler;
|
c := ccompiler;
|
||||||
it := PStrEntry(list.head);
|
|
||||||
|
|
||||||
options := compileOptions;
|
options := compileOptions;
|
||||||
if optCDebug in gGlobalOptions then addStr(options, ' ' + getDebug(c));
|
if optCDebug in gGlobalOptions then addStr(options, ' ' + getDebug(c));
|
||||||
if optOptimizeSpeed in gOptions then addStr(options, ' ' + getOptSpeed(c))
|
if optOptimizeSpeed in gOptions then addStr(options, ' ' + getOptSpeed(c))
|
||||||
|
|
@ -413,31 +441,43 @@ begin
|
||||||
includeCmd := cc[c].includeCmd; // this is more complex than needed, but
|
includeCmd := cc[c].includeCmd; // this is more complex than needed, but
|
||||||
// a workaround of a FPC bug...
|
// a workaround of a FPC bug...
|
||||||
addStr(includeCmd, libpath);
|
addStr(includeCmd, libpath);
|
||||||
compilePattern := JoinPath(ccompilerpath, cc[c].compile);
|
compilePattern := quoteIfSpaceExists(
|
||||||
|
JoinPath(ccompilerpath, cc[c].compilerExe));
|
||||||
end
|
end
|
||||||
else begin
|
else begin
|
||||||
includeCmd := '';
|
includeCmd := '';
|
||||||
compilePattern := cc[c].compile
|
compilePattern := cc[c].compilerExe
|
||||||
end;
|
end;
|
||||||
|
|
||||||
while it <> nil do begin
|
|
||||||
// call the C compiler for the .c file:
|
|
||||||
if targetOS = hostOS then
|
if targetOS = hostOS then
|
||||||
cfile := it.data
|
cfile := cfilename
|
||||||
else
|
else
|
||||||
cfile := extractFileName(it.data);
|
cfile := extractFileName(cfilename);
|
||||||
|
|
||||||
if not isExternal or (targetOS <> hostOS) then
|
if not isExternal or (targetOS <> hostOS) then
|
||||||
objfile := toObjFile(cfile)
|
objfile := toObjFile(cfile)
|
||||||
else
|
else
|
||||||
objfile := completeCFilePath(toObjFile(cfile));
|
objfile := completeCFilePath(toObjFile(cfile));
|
||||||
|
|
||||||
compileCmd := format(compilePattern,
|
result := compilePattern +{&} ' ' +{&} format(cc[c].compileTmpl,
|
||||||
['file', AppendFileExt(cfile, cExt),
|
['file', AppendFileExt(cfile, cExt),
|
||||||
'objfile', objfile,
|
'objfile', objfile,
|
||||||
'options', options,
|
'options', options,
|
||||||
'include', includeCmd
|
'include', includeCmd,
|
||||||
|
'nimrod', getPrefixDir(),
|
||||||
|
'lib', libpath
|
||||||
]);
|
]);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure CompileCFile(const list: TLinkedList;
|
||||||
|
var script: PRope; isExternal: Boolean);
|
||||||
|
var
|
||||||
|
it: PStrEntry;
|
||||||
|
compileCmd: string;
|
||||||
|
begin
|
||||||
|
it := PStrEntry(list.head);
|
||||||
|
while it <> nil do begin
|
||||||
|
// call the C compiler for the .c file:
|
||||||
|
compileCmd := getCompileCFileCmd(it.data, isExternal);
|
||||||
if not (optCompileOnly in gGlobalOptions) then
|
if not (optCompileOnly in gGlobalOptions) then
|
||||||
execExternalProgram(compileCmd);
|
execExternalProgram(compileCmd);
|
||||||
if (optGenScript in gGlobalOptions) then begin
|
if (optGenScript in gGlobalOptions) then begin
|
||||||
|
|
@ -469,9 +509,9 @@ begin
|
||||||
if not (optNoLinking in gGlobalOptions) then begin
|
if not (optNoLinking in gGlobalOptions) then begin
|
||||||
// call the linker:
|
// call the linker:
|
||||||
if (hostOS <> targetOS) then
|
if (hostOS <> targetOS) then
|
||||||
linkCmd := cc[c].link
|
linkCmd := cc[c].linkerExe
|
||||||
else
|
else
|
||||||
linkCmd := JoinPath(ccompilerpath, cc[c].link);
|
linkCmd := quoteIfSpaceExists(JoinPath(ccompilerpath, cc[c].linkerExe));
|
||||||
|
|
||||||
if optGenDynLib in gGlobalOptions then
|
if optGenDynLib in gGlobalOptions then
|
||||||
buildDll := cc[c].buildDll
|
buildDll := cc[c].buildDll
|
||||||
|
|
@ -506,12 +546,14 @@ begin
|
||||||
it := PStrEntry(it.next);
|
it := PStrEntry(it.next);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
linkCmd := format(linkCmd, [
|
linkCmd := linkCmd +{&} ' ' +{&} format(cc[c].linkTmpl, [
|
||||||
'builddll', builddll,
|
'builddll', builddll,
|
||||||
'buildgui', buildgui,
|
'buildgui', buildgui,
|
||||||
'options', linkOptions,
|
'options', linkOptions,
|
||||||
'objfiles', objfiles,
|
'objfiles', objfiles,
|
||||||
'exefile', exefile
|
'exefile', exefile,
|
||||||
|
'nimrod', getPrefixDir(),
|
||||||
|
'lib', libpath
|
||||||
]);
|
]);
|
||||||
if not (optCompileOnly in gGlobalOptions) then
|
if not (optCompileOnly in gGlobalOptions) then
|
||||||
execExternalProgram(linkCmd);
|
execExternalProgram(linkCmd);
|
||||||
|
|
|
||||||
175
nim/genhelp.pas
175
nim/genhelp.pas
|
|
@ -1,175 +0,0 @@
|
||||||
//
|
|
||||||
//
|
|
||||||
// The Nimrod Compiler
|
|
||||||
// (c) Copyright 2008 Andreas Rumpf
|
|
||||||
//
|
|
||||||
// See the file "copying.txt", included in this
|
|
||||||
// distribution, for details about the copyright.
|
|
||||||
//
|
|
||||||
|
|
||||||
unit genhelp;
|
|
||||||
|
|
||||||
// This module contains some helper routines used by the different
|
|
||||||
// code generators.
|
|
||||||
|
|
||||||
interface
|
|
||||||
|
|
||||||
{$include 'config.inc'}
|
|
||||||
|
|
||||||
uses
|
|
||||||
nsystem,
|
|
||||||
ast, astalgo, trees, msgs, options, platform;
|
|
||||||
|
|
||||||
function hasSideEffect(t: PNode): Boolean;
|
|
||||||
|
|
||||||
function ReturnsNewThing(op: PNode): Boolean;
|
|
||||||
|
|
||||||
|
|
||||||
function containsGarbageCollectedRef(typ: PType): Boolean;
|
|
||||||
// returns true if typ contains a reference, sequence or string (all the things
|
|
||||||
// that are garbage-collected)
|
|
||||||
|
|
||||||
function containsHiddenPointer(typ: PType): Boolean;
|
|
||||||
// returns true if typ contains a string, table or sequence (all the things
|
|
||||||
// that need to be copied deeply)
|
|
||||||
|
|
||||||
function containsObject(typ: PType): Boolean;
|
|
||||||
// Returns true if typ contains an object type directly; then it has to
|
|
||||||
// be initialized in a complex way that sets up the typeid field.
|
|
||||||
|
|
||||||
function isGarbageCollected(typ: PType): Boolean;
|
|
||||||
|
|
||||||
function pointerOf(typ: PType): PType;
|
|
||||||
|
|
||||||
implementation
|
|
||||||
|
|
||||||
function pointerOf(typ: PType): PType;
|
|
||||||
begin
|
|
||||||
result := newType(unknownLineInfo, tyPtr);
|
|
||||||
result.baseType := typ;
|
|
||||||
result.align := platform.PtrSize;
|
|
||||||
result.size := platform.PtrSize;
|
|
||||||
end;
|
|
||||||
|
|
||||||
function isGarbageCollected(typ: PType): Boolean;
|
|
||||||
begin
|
|
||||||
result := typ.Kind in [tyTable, tyRef, tySequence, tyString]
|
|
||||||
end;
|
|
||||||
|
|
||||||
function ReturnsNewThing(op: PNode): Boolean;
|
|
||||||
var
|
|
||||||
s: PSym;
|
|
||||||
begin
|
|
||||||
result := false;
|
|
||||||
if op.kind = nkCall then begin
|
|
||||||
if op.sons[0].kind = nkSym then begin
|
|
||||||
s := op.sons[0].sym;
|
|
||||||
result := (sfReturnsNew in s.flags)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
else if op.typ.Kind = tyArrayConstr then
|
|
||||||
result := true // array constructor returns a newly allocated thing
|
|
||||||
end;
|
|
||||||
|
|
||||||
function containsHiddenPointer(typ: PType): Boolean;
|
|
||||||
var
|
|
||||||
t: PType;
|
|
||||||
i: int;
|
|
||||||
begin
|
|
||||||
t := typ;
|
|
||||||
result := false;
|
|
||||||
if t = nil then exit;
|
|
||||||
case t.Kind of
|
|
||||||
tySequence, tyString, tyTable: result := true;
|
|
||||||
tyArray, tyArrayConstr, tyOpenArray:
|
|
||||||
result := containsHiddenPointer(t.baseType);
|
|
||||||
tySubtype: result := containsHiddenPointer(typ.baseType);
|
|
||||||
tyRecord, tyObject: begin
|
|
||||||
if (t.baseType <> nil) and containsHiddenPointer(t.baseType) then
|
|
||||||
result := true
|
|
||||||
else
|
|
||||||
// walk through all fields:
|
|
||||||
for i := 0 to seqTableLen(t.symList)-1 do
|
|
||||||
if containsHiddenPointer(seqTableAt(t.symList, i).typ) then begin
|
|
||||||
result := true; break
|
|
||||||
end;
|
|
||||||
end
|
|
||||||
else result := false
|
|
||||||
end
|
|
||||||
end;
|
|
||||||
|
|
||||||
function containsGarbageCollectedRef(typ: PType): Boolean;
|
|
||||||
var
|
|
||||||
t: PType;
|
|
||||||
i: int;
|
|
||||||
begin
|
|
||||||
t := typ;
|
|
||||||
result := false;
|
|
||||||
if t = nil then exit;
|
|
||||||
case t.Kind of
|
|
||||||
tySequence, tyRef, tyString, tyTable: result := true;
|
|
||||||
tyArray: result := containsGarbageCollectedRef(t.baseType);
|
|
||||||
tyRecord, tyObject: begin
|
|
||||||
if (t.baseType <> nil) and containsGarbageCollectedRef(t.baseType) then
|
|
||||||
result := true
|
|
||||||
else
|
|
||||||
// walk through all fields:
|
|
||||||
for i := 0 to seqTableLen(t.symList)-1 do
|
|
||||||
if containsGarbageCollectedRef(SeqTableAt(t.symList, i).typ) then
|
|
||||||
begin
|
|
||||||
result := true; break
|
|
||||||
end;
|
|
||||||
end
|
|
||||||
else result := false
|
|
||||||
end
|
|
||||||
end;
|
|
||||||
|
|
||||||
function containsObject(typ: PType): Boolean;
|
|
||||||
var
|
|
||||||
t: PType;
|
|
||||||
i: int;
|
|
||||||
begin
|
|
||||||
t := typ;
|
|
||||||
result := false;
|
|
||||||
if t = nil then exit;
|
|
||||||
case t.Kind of
|
|
||||||
tyArray, tyArrayConstr:
|
|
||||||
result := containsObject(t.baseType);
|
|
||||||
tyObject: result := true;
|
|
||||||
tySubtype: result := containsObject(typ.baseType);
|
|
||||||
tyRecord: begin
|
|
||||||
// walk through all fields:
|
|
||||||
for i := 0 to seqTableLen(t.symList)-1 do
|
|
||||||
if containsObject(SeqTableAt(t.symList, i).typ) then begin
|
|
||||||
result := true; break
|
|
||||||
end;
|
|
||||||
end
|
|
||||||
else result := false
|
|
||||||
end
|
|
||||||
end;
|
|
||||||
|
|
||||||
function hasSideEffect(t: PNode): Boolean;
|
|
||||||
{var
|
|
||||||
it: PNode; }
|
|
||||||
begin
|
|
||||||
result := t.kind in [nkCall, nkArrayConstr, nkRecordConstr, nkSetConstr]
|
|
||||||
// assume side effect for operations
|
|
||||||
{
|
|
||||||
if t.Kind = nkOperation then begin
|
|
||||||
// this is for function pointers:
|
|
||||||
if hasSideEffect(t.left) then begin
|
|
||||||
result := true; exit
|
|
||||||
end;
|
|
||||||
it := t.right;
|
|
||||||
while it <> nil do begin
|
|
||||||
if hasSideEffect(it) then begin
|
|
||||||
result := true; exit
|
|
||||||
end;
|
|
||||||
it := it.next
|
|
||||||
end;
|
|
||||||
result := true
|
|
||||||
end;
|
|
||||||
result := false }
|
|
||||||
end;
|
|
||||||
|
|
||||||
end.
|
|
||||||
|
|
@ -60,7 +60,9 @@ type
|
||||||
function nextPowerOfTwo(x: int): int;
|
function nextPowerOfTwo(x: int): int;
|
||||||
begin
|
begin
|
||||||
result := x -{%} 1;
|
result := x -{%} 1;
|
||||||
result := result or (result shr 32);
|
// complicated, to make it a nop if sizeof(int) == 4,
|
||||||
|
// because shifting more than 31 bits is undefined in C
|
||||||
|
result := result or (result shr ((sizeof(int)-4)* 32));
|
||||||
result := result or (result shr 16);
|
result := result or (result shr 16);
|
||||||
result := result or (result shr 8);
|
result := result or (result shr 8);
|
||||||
result := result or (result shr 4);
|
result := result or (result shr 4);
|
||||||
|
|
|
||||||
|
|
@ -137,6 +137,11 @@ procedure initGeneralTokenizer(var g: TGeneralTokenizer;
|
||||||
begin
|
begin
|
||||||
{@ignore} fillChar(g, sizeof(g), 0); {@emit}
|
{@ignore} fillChar(g, sizeof(g), 0); {@emit}
|
||||||
g.buf := PChar(buf);
|
g.buf := PChar(buf);
|
||||||
|
g.kind := low(TTokenClass);
|
||||||
|
g.start := 0;
|
||||||
|
g.len := 0;
|
||||||
|
g.pos := 0;
|
||||||
|
g.state := low(TTokenClass);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure deinitGeneralTokenizer(var g: TGeneralTokenizer);
|
procedure deinitGeneralTokenizer(var g: TGeneralTokenizer);
|
||||||
|
|
|
||||||
|
|
@ -42,8 +42,9 @@ var
|
||||||
j: int;
|
j: int;
|
||||||
etyp: PType; // enumeration type
|
etyp: PType; // enumeration type
|
||||||
begin
|
begin
|
||||||
copy := copySym(s, s.owner);
|
//copy := copySym(s, true);
|
||||||
copy.ast := s.ast; // BUGFIX
|
//copy.ast := s.ast;
|
||||||
|
copy := s; // do not copy symbols when importing!
|
||||||
// check if we have already a symbol of the same name:
|
// check if we have already a symbol of the same name:
|
||||||
check := StrTableGet(c.tab.stack[importTablePos], s.name);
|
check := StrTableGet(c.tab.stack[importTablePos], s.name);
|
||||||
if check <> nil then begin
|
if check <> nil then begin
|
||||||
|
|
@ -55,17 +56,17 @@ begin
|
||||||
end;
|
end;
|
||||||
StrTableAdd(c.tab.stack[importTablePos], copy);
|
StrTableAdd(c.tab.stack[importTablePos], copy);
|
||||||
if s.kind = skType then begin
|
if s.kind = skType then begin
|
||||||
// types are special: we need to copy types but need to
|
|
||||||
// consider private fields
|
|
||||||
etyp := s.typ;
|
etyp := s.typ;
|
||||||
if etyp.kind = tyEnum then begin
|
if etyp.kind = tyEnum then begin
|
||||||
for j := 0 to sonsLen(etyp.n)-1 do begin
|
for j := 0 to sonsLen(etyp.n)-1 do begin
|
||||||
e := etyp.n.sons[j].sym;
|
e := etyp.n.sons[j].sym;
|
||||||
assert(e.Kind = skEnumField);
|
if (e.Kind = skEnumField) then rawImportSymbol(c, e)
|
||||||
rawImportSymbol(c, e)
|
else InternalError(s.info, 'rawImportSymbol');
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end;
|
end
|
||||||
|
else if s.kind = skConverter then
|
||||||
|
addConverter(c, s);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure importSymbol(c: PContext; ident: PNode; fromMod: PSym);
|
procedure importSymbol(c: PContext; ident: PNode; fromMod: PSym);
|
||||||
|
|
@ -73,18 +74,20 @@ var
|
||||||
s, e: PSym;
|
s, e: PSym;
|
||||||
it: TIdentIter;
|
it: TIdentIter;
|
||||||
begin
|
begin
|
||||||
assert(ident.kind = nkIdent);
|
if (ident.kind <> nkIdent) then InternalError(ident.info, 'importSymbol');
|
||||||
s := StrTableGet(fromMod.tab, ident.ident);
|
s := StrTableGet(fromMod.tab, ident.ident);
|
||||||
if s = nil then
|
if s = nil then
|
||||||
liMessage(ident.info, errUndeclaredIdentifier, ident.ident.s);
|
liMessage(ident.info, errUndeclaredIdentifier, ident.ident.s);
|
||||||
assert(s.Kind in ExportableSymKinds);
|
if not (s.Kind in ExportableSymKinds) then
|
||||||
|
InternalError(ident.info, 'importSymbol: 2');
|
||||||
// for an enumeration we have to add all identifiers
|
// for an enumeration we have to add all identifiers
|
||||||
case s.Kind of
|
case s.Kind of
|
||||||
skProc, skIterator, skMacro, skTemplate: begin
|
skProc, skIterator, skMacro, skTemplate, skConverter: begin
|
||||||
// for a overloadable syms add all overloaded routines
|
// for a overloadable syms add all overloaded routines
|
||||||
e := InitIdentIter(it, fromMod.tab, s.name);
|
e := InitIdentIter(it, fromMod.tab, s.name);
|
||||||
while e <> nil do begin
|
while e <> nil do begin
|
||||||
assert(e.name.id = s.Name.id);
|
if (e.name.id <> s.Name.id) then
|
||||||
|
InternalError(ident.info, 'importSymbol: 3');
|
||||||
rawImportSymbol(c, e);
|
rawImportSymbol(c, e);
|
||||||
e := NextIdentIter(it, fromMod.tab);
|
e := NextIdentIter(it, fromMod.tab);
|
||||||
end
|
end
|
||||||
|
|
@ -101,8 +104,11 @@ begin
|
||||||
s := InitTabIter(i, fromMod.tab);
|
s := InitTabIter(i, fromMod.tab);
|
||||||
while s <> nil do begin
|
while s <> nil do begin
|
||||||
if s.kind <> skModule then begin
|
if s.kind <> skModule then begin
|
||||||
assert(s.Kind in ExportableSymKinds);
|
if s.kind <> skEnumField then begin
|
||||||
|
if not (s.Kind in ExportableSymKinds) then
|
||||||
|
InternalError(s.info, 'importAllSymbols');
|
||||||
rawImportSymbol(c, s); // this is correct!
|
rawImportSymbol(c, s); // this is correct!
|
||||||
|
end
|
||||||
end;
|
end;
|
||||||
s := NextIter(i, fromMod.tab)
|
s := NextIter(i, fromMod.tab)
|
||||||
end
|
end
|
||||||
|
|
@ -129,6 +135,7 @@ var
|
||||||
i: int;
|
i: int;
|
||||||
begin
|
begin
|
||||||
result := n;
|
result := n;
|
||||||
|
checkMinSonsLen(n, 2);
|
||||||
m := c.ImportModule(getModuleFile(n.sons[0]), c.b);
|
m := c.ImportModule(getModuleFile(n.sons[0]), c.b);
|
||||||
n.sons[0] := newSymNode(m);
|
n.sons[0] := newSymNode(m);
|
||||||
addDecl(c, m); // add symbol to symbol table of module
|
addDecl(c, m); // add symbol to symbol table of module
|
||||||
|
|
@ -140,7 +147,7 @@ var
|
||||||
i: int;
|
i: int;
|
||||||
x: PNode;
|
x: PNode;
|
||||||
begin
|
begin
|
||||||
result := newNode(nkStmtList);
|
result := newNodeI(nkStmtList, n.info);
|
||||||
for i := 0 to sonsLen(n)-1 do begin
|
for i := 0 to sonsLen(n)-1 do begin
|
||||||
x := c.includeFile(getModuleFile(n.sons[i]));
|
x := c.includeFile(getModuleFile(n.sons[i]));
|
||||||
x := semStmt(c, x);
|
x := semStmt(c, x);
|
||||||
|
|
|
||||||
|
|
@ -21,11 +21,12 @@ type
|
||||||
newOwner: PSym;
|
newOwner: PSym;
|
||||||
instantiator: TLineInfo;
|
instantiator: TLineInfo;
|
||||||
end;
|
end;
|
||||||
PInstClosure = ^TInstantiateClosure;
|
PInstantiateClosure = ^TInstantiateClosure;
|
||||||
|
PInstClosure = PInstantiateClosure;
|
||||||
|
|
||||||
function instantiateTree(var c: TInstantiateClosure; t: PNode): PNode; forward;
|
function instantiateTree(c: PInstantiateClosure; t: PNode): PNode; forward;
|
||||||
|
function instantiateSym(c: PInstantiateClosure; sym: PSym): PSym; forward;
|
||||||
function instantiateSym(var c: TInstantiateClosure; sym: PSym): PSym; forward;
|
function instantiateType(c: PInstantiateClosure; typ: PType): PType; forward;
|
||||||
|
|
||||||
function containsGenericTypeIter(t: PType; closure: PObject): bool;
|
function containsGenericTypeIter(t: PType; closure: PObject): bool;
|
||||||
begin
|
begin
|
||||||
|
|
@ -37,35 +38,58 @@ begin
|
||||||
result := iterOverType(t, containsGenericTypeIter, nil);
|
result := iterOverType(t, containsGenericTypeIter, nil);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function instTypeNode(c: PInstantiateClosure; n: PNode): PNode;
|
||||||
function instantiateTypeMutator(typ: PType; c: PObject): PType;
|
var
|
||||||
|
i: int;
|
||||||
begin
|
begin
|
||||||
result := PType(idTableGet(PInstClosure(c).mapping, typ));
|
result := nil;
|
||||||
|
if n <> nil then begin
|
||||||
|
result := copyNode(n);
|
||||||
|
result.typ := instantiateType(c, n.typ);
|
||||||
|
case n.kind of
|
||||||
|
nkNone..nkNilLit: begin // a leaf
|
||||||
|
end;
|
||||||
|
else begin
|
||||||
|
for i := 0 to sonsLen(n)-1 do
|
||||||
|
addSon(result, instTypeNode(c, n.sons[i]));
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end;
|
||||||
|
|
||||||
|
function instantiateType(c: PInstantiateClosure; typ: PType): PType;
|
||||||
|
var
|
||||||
|
i: int;
|
||||||
|
begin
|
||||||
|
result := PType(idTableGet(c.mapping, typ));
|
||||||
if result <> nil then exit;
|
if result <> nil then exit;
|
||||||
if containsGenericType(typ) then begin
|
if containsGenericType(typ) then begin
|
||||||
result := copyType(typ, PInstClosure(c).newOwner);
|
result := copyType(typ, c.newOwner);
|
||||||
idTablePut(PInstClosure(c).mapping, typ, result)
|
idTablePut(c.mapping, typ, result); // to avoid cycles
|
||||||
|
for i := 0 to sonsLen(result)-1 do
|
||||||
|
result.sons[i] := instantiateType(c, result.sons[i]);
|
||||||
|
if result.n <> nil then
|
||||||
|
result.n := instTypeNode(c, result.n);
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
result := typ;
|
result := typ;
|
||||||
if result.Kind in GenericTypes then begin
|
if result.Kind in GenericTypes then begin
|
||||||
liMessage(PInstClosure(c).instantiator, errCannotInstantiateX,
|
liMessage(c.instantiator, errCannotInstantiateX,
|
||||||
TypeToString(typ, preferName));
|
TypeToString(typ, preferName));
|
||||||
|
end
|
||||||
|
else if result.kind = tyVar then begin
|
||||||
|
if result.sons[0].kind = tyVar then
|
||||||
|
liMessage(c.instantiator, errVarVarTypeNotAllowed);
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function instantiateType(var c: TInstantiateClosure; typ: PType): PType;
|
function instantiateSym(c: PInstantiateClosure; sym: PSym): PSym;
|
||||||
begin
|
|
||||||
result := mutateType(typ, instantiateTypeMutator, {@cast}PObject(addr(c)));
|
|
||||||
end;
|
|
||||||
|
|
||||||
function instantiateSym(var c: TInstantiateClosure; sym: PSym): PSym;
|
|
||||||
begin
|
begin
|
||||||
if sym = nil then begin result := nil; exit end; // BUGFIX
|
if sym = nil then begin result := nil; exit end; // BUGFIX
|
||||||
result := PSym(idTableGet(c.mapping, sym));
|
result := PSym(idTableGet(c.mapping, sym));
|
||||||
if (result = nil) then begin
|
if (result = nil) then begin
|
||||||
if (sym.owner.id = c.fn.id) or (sym.id = c.fn.id) then begin
|
if (sym.owner.id = c.fn.id) or (sym.id = c.fn.id) then begin
|
||||||
result := copySym(sym, nil);
|
result := copySym(sym);
|
||||||
if sym.id = c.fn.id then c.newOwner := result;
|
if sym.id = c.fn.id then c.newOwner := result;
|
||||||
include(result.flags, sfIsCopy);
|
include(result.flags, sfIsCopy);
|
||||||
idTablePut(c.mapping, sym, result); // BUGFIX
|
idTablePut(c.mapping, sym, result); // BUGFIX
|
||||||
|
|
@ -83,7 +107,7 @@ begin
|
||||||
end
|
end
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function instantiateTree(var c: TInstantiateClosure; t: PNode): PNode;
|
function instantiateTree(c: PInstantiateClosure; t: PNode): PNode;
|
||||||
var
|
var
|
||||||
len, i: int;
|
len, i: int;
|
||||||
begin
|
begin
|
||||||
|
|
@ -124,7 +148,8 @@ begin
|
||||||
q := n.sons[i].sym;
|
q := n.sons[i].sym;
|
||||||
s := newSym(skType, q.name, getCurrOwner(c));
|
s := newSym(skType, q.name, getCurrOwner(c));
|
||||||
t := PType(IdTableGet(pt, q.typ));
|
t := PType(IdTableGet(pt, q.typ));
|
||||||
if t = nil then liMessage(n.sons[i].info, errCannotInstantiateX, s.name.s);
|
if t = nil then
|
||||||
|
liMessage(n.sons[i].info, errCannotInstantiateX, s.name.s);
|
||||||
assert(t.kind <> tyGenericParam);
|
assert(t.kind <> tyGenericParam);
|
||||||
s.typ := t;
|
s.typ := t;
|
||||||
addDecl(c, s);
|
addDecl(c, s);
|
||||||
|
|
@ -138,7 +163,8 @@ var
|
||||||
begin
|
begin
|
||||||
result := nil;
|
result := nil;
|
||||||
for i := 0 to sonsLen(c.generics)-1 do begin
|
for i := 0 to sonsLen(c.generics)-1 do begin
|
||||||
assert(c.generics.sons[i].kind = nkExprEqExpr);
|
if c.generics.sons[i].kind <> nkExprEqExpr then
|
||||||
|
InternalError(genericSym.info, 'GenericCacheGet');
|
||||||
a := c.generics.sons[i].sons[0].sym;
|
a := c.generics.sons[i].sons[0].sym;
|
||||||
if genericSym.id = a.id then begin
|
if genericSym.id = a.id then begin
|
||||||
b := c.generics.sons[i].sons[1].sym;
|
b := c.generics.sons[i].sons[1].sym;
|
||||||
|
|
@ -173,8 +199,8 @@ var
|
||||||
n: PNode;
|
n: PNode;
|
||||||
begin
|
begin
|
||||||
oldP := c.p; // restore later
|
oldP := c.p; // restore later
|
||||||
result := copySym(fn, getCurrOwner(c));
|
result := copySym(fn);
|
||||||
result.id := getId();
|
result.owner := getCurrOwner(c);
|
||||||
n := copyTree(fn.ast);
|
n := copyTree(fn.ast);
|
||||||
result.ast := n;
|
result.ast := n;
|
||||||
pushOwner(c, result);
|
pushOwner(c, result);
|
||||||
|
|
@ -202,7 +228,7 @@ begin
|
||||||
addDecl(c, result);
|
addDecl(c, result);
|
||||||
if n.sons[codePos] <> nil then begin
|
if n.sons[codePos] <> nil then begin
|
||||||
c.p := newProcCon(result);
|
c.p := newProcCon(result);
|
||||||
if result.kind = skProc then begin
|
if result.kind in [skProc, skConverter] then begin
|
||||||
addResult(c, result.typ.sons[0], n.info);
|
addResult(c, result.typ.sons[0], n.info);
|
||||||
addResultNode(c, n);
|
addResultNode(c, n);
|
||||||
end;
|
end;
|
||||||
|
|
@ -221,8 +247,12 @@ end;
|
||||||
function generateTypeInstance(p: PContext; const pt: TIdTable;
|
function generateTypeInstance(p: PContext; const pt: TIdTable;
|
||||||
const instantiator: TLineInfo; t: PType): PType;
|
const instantiator: TLineInfo; t: PType): PType;
|
||||||
var
|
var
|
||||||
c: TInstantiateClosure;
|
c: PInstantiateClosure;
|
||||||
begin
|
begin
|
||||||
|
new(c);
|
||||||
|
{@ignore}
|
||||||
|
fillChar(c^, sizeof(c^), 0);
|
||||||
|
{@emit}
|
||||||
c.mapping := pt; // making a copy is not necessary
|
c.mapping := pt; // making a copy is not necessary
|
||||||
c.fn := nil;
|
c.fn := nil;
|
||||||
c.instantiator := instantiator;
|
c.instantiator := instantiator;
|
||||||
|
|
|
||||||
|
|
@ -227,7 +227,7 @@ begin
|
||||||
L.linenumber := 1; // lines start at 1
|
L.linenumber := 1; // lines start at 1
|
||||||
L.fileOpened := false;
|
L.fileOpened := false;
|
||||||
if L.bufLen > 0 then begin
|
if L.bufLen > 0 then begin
|
||||||
copyMem(L.buf, addr(buffer[strStart]), L.bufLen);
|
copyMem(L.buf, {@cast}pointer(buffer), L.bufLen);
|
||||||
L.buf[L.bufLen-1] := EndOfFile;
|
L.buf[L.bufLen-1] := EndOfFile;
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
|
|
|
||||||
|
|
@ -12,8 +12,7 @@
|
||||||
function getSymRepr(s: PSym): string;
|
function getSymRepr(s: PSym): string;
|
||||||
begin
|
begin
|
||||||
case s.kind of
|
case s.kind of
|
||||||
skProc, skConverter, skIterator:
|
skProc, skConverter, skIterator: result := getProcHeader(s);
|
||||||
result := getProcHeader(s);
|
|
||||||
else result := s.name.s
|
else result := s.name.s
|
||||||
end
|
end
|
||||||
end;
|
end;
|
||||||
|
|
@ -24,7 +23,7 @@ var
|
||||||
s: PSym;
|
s: PSym;
|
||||||
begin
|
begin
|
||||||
// check if all symbols have been used and defined:
|
// check if all symbols have been used and defined:
|
||||||
assert(tab.tos <= length(tab.stack));
|
if (tab.tos > length(tab.stack)) then InternalError('CloseScope');
|
||||||
s := InitTabIter(it, tab.stack[tab.tos-1]);
|
s := InitTabIter(it, tab.stack[tab.tos-1]);
|
||||||
while s <> nil do begin
|
while s <> nil do begin
|
||||||
if sfForward in s.flags then
|
if sfForward in s.flags then
|
||||||
|
|
@ -59,7 +58,8 @@ procedure addOverloadableSymAt(c: PContext; fn: PSym; at: Natural);
|
||||||
var
|
var
|
||||||
check: PSym;
|
check: PSym;
|
||||||
begin
|
begin
|
||||||
assert(fn.kind in OverloadableSyms);
|
if not (fn.kind in OverloadableSyms) then
|
||||||
|
InternalError(fn.info, 'addOverloadableSymAt');
|
||||||
check := StrTableGet(c.tab.stack[at], fn.name);
|
check := StrTableGet(c.tab.stack[at], fn.name);
|
||||||
if (check <> nil) and (check.Kind <> fn.kind) then
|
if (check <> nil) and (check.Kind <> fn.kind) then
|
||||||
liMessage(fn.info, errAttemptToRedefine, fn.Name.s);
|
liMessage(fn.info, errAttemptToRedefine, fn.Name.s);
|
||||||
|
|
@ -70,7 +70,7 @@ procedure AddInterfaceDeclAux(c: PContext; sym: PSym);
|
||||||
begin
|
begin
|
||||||
if (sfInInterface in sym.flags) then begin
|
if (sfInInterface in sym.flags) then begin
|
||||||
// add to interface:
|
// add to interface:
|
||||||
assert(c.module <> nil);
|
if c.module = nil then InternalError(sym.info, 'AddInterfaceDeclAux');
|
||||||
StrTableAdd(c.module.tab, sym);
|
StrTableAdd(c.module.tab, sym);
|
||||||
end;
|
end;
|
||||||
if getCurrOwner(c).kind = skModule then
|
if getCurrOwner(c).kind = skModule then
|
||||||
|
|
@ -92,12 +92,21 @@ end;
|
||||||
function lookUp(c: PContext; n: PNode): PSym;
|
function lookUp(c: PContext; n: PNode): PSym;
|
||||||
// Looks up a symbol. Generates an error in case of nil.
|
// Looks up a symbol. Generates an error in case of nil.
|
||||||
begin
|
begin
|
||||||
if n.kind = nkAccQuoted then result := lookup(c, n.sons[0])
|
case n.kind of
|
||||||
else begin
|
nkAccQuoted: result := lookup(c, n.sons[0]);
|
||||||
assert(n.kind = nkIdent);
|
nkSym: begin
|
||||||
result := SymtabGet(c.Tab, n.ident);
|
result := SymtabGet(c.Tab, n.sym.name);
|
||||||
if result = nil then liMessage(n.info, errUndeclaredIdentifier, n.ident.s);
|
if result = nil then
|
||||||
|
liMessage(n.info, errUndeclaredIdentifier, n.sym.name.s);
|
||||||
include(result.flags, sfUsed);
|
include(result.flags, sfUsed);
|
||||||
|
end;
|
||||||
|
nkIdent: begin
|
||||||
|
result := SymtabGet(c.Tab, n.ident);
|
||||||
|
if result = nil then
|
||||||
|
liMessage(n.info, errUndeclaredIdentifier, n.ident.s);
|
||||||
|
include(result.flags, sfUsed);
|
||||||
|
end
|
||||||
|
else InternalError(n.info, 'lookUp');
|
||||||
end
|
end
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
@ -115,6 +124,14 @@ begin
|
||||||
and StrTableContains(c.AmbigiousSymbols, result) then
|
and StrTableContains(c.AmbigiousSymbols, result) then
|
||||||
liMessage(n.info, errUseQualifier, n.ident.s)
|
liMessage(n.info, errUseQualifier, n.ident.s)
|
||||||
end;
|
end;
|
||||||
|
nkSym: begin
|
||||||
|
result := SymtabGet(c.Tab, n.sym.name);
|
||||||
|
if result = nil then
|
||||||
|
liMessage(n.info, errUndeclaredIdentifier, n.sym.name.s)
|
||||||
|
else if ambigiousCheck
|
||||||
|
and StrTableContains(c.AmbigiousSymbols, result) then
|
||||||
|
liMessage(n.info, errUseQualifier, n.sym.name.s)
|
||||||
|
end;
|
||||||
nkDotExpr, nkQualified: begin
|
nkDotExpr, nkQualified: begin
|
||||||
result := nil;
|
result := nil;
|
||||||
m := qualifiedLookUp(c, n.sons[0], false);
|
m := qualifiedLookUp(c, n.sons[0], false);
|
||||||
|
|
@ -165,6 +182,15 @@ begin
|
||||||
result := InitIdentIter(o.it, c.tab.stack[o.stackPtr], n.ident);
|
result := InitIdentIter(o.it, c.tab.stack[o.stackPtr], n.ident);
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
nkSym: begin
|
||||||
|
o.stackPtr := c.tab.tos;
|
||||||
|
o.mode := oimNoQualifier;
|
||||||
|
while (result = nil) do begin
|
||||||
|
dec(o.stackPtr);
|
||||||
|
if o.stackPtr < 0 then break;
|
||||||
|
result := InitIdentIter(o.it, c.tab.stack[o.stackPtr], n.sym.name);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
nkDotExpr, nkQualified: begin
|
nkDotExpr, nkQualified: begin
|
||||||
o.mode := oimOtherModule;
|
o.mode := oimOtherModule;
|
||||||
o.m := qualifiedLookUp(c, n.sons[0], false);
|
o.m := qualifiedLookUp(c, n.sons[0], false);
|
||||||
|
|
@ -199,7 +225,8 @@ begin
|
||||||
while (result = nil) do begin
|
while (result = nil) do begin
|
||||||
dec(o.stackPtr);
|
dec(o.stackPtr);
|
||||||
if o.stackPtr < 0 then break;
|
if o.stackPtr < 0 then break;
|
||||||
result := InitIdentIter(o.it, c.tab.stack[o.stackPtr], n.ident);
|
result := InitIdentIter(o.it, c.tab.stack[o.stackPtr], o.it.name);
|
||||||
|
// BUGFIX: o.it.name <-> n.ident
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
else result := nil;
|
else result := nil;
|
||||||
|
|
|
||||||
29
nim/main.pas
29
nim/main.pas
|
|
@ -17,7 +17,8 @@ interface
|
||||||
uses
|
uses
|
||||||
nsystem, strutils, ast, astalgo, scanner, pnimsyn, rnimsyn, options, msgs,
|
nsystem, strutils, ast, astalgo, scanner, pnimsyn, rnimsyn, options, msgs,
|
||||||
nos, lists, condsyms, paslex, pasparse, rodgen, ropes, trees,
|
nos, lists, condsyms, paslex, pasparse, rodgen, ropes, trees,
|
||||||
wordrecg, sem, idents, magicsys, backends, docgen, extccomp, cgen;
|
wordrecg, sem, idents, magicsys, backends, docgen, extccomp, cgen,
|
||||||
|
platform, ecmasgen;
|
||||||
|
|
||||||
procedure MainCommand(const cmd, filename: string);
|
procedure MainCommand(const cmd, filename: string);
|
||||||
|
|
||||||
|
|
@ -109,7 +110,9 @@ begin
|
||||||
// compile the module
|
// compile the module
|
||||||
// XXX: here caching could be implemented
|
// XXX: here caching could be implemented
|
||||||
result := compileModule(filename, backend, false, false);
|
result := compileModule(filename, backend, false, false);
|
||||||
end;
|
end
|
||||||
|
else if sfSystemModule in result.flags then
|
||||||
|
liMessage(result.info, errAttemptToRedefine, result.Name.s);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function CompileModule(const filename: string; backend: PBackend;
|
function CompileModule(const filename: string; backend: PBackend;
|
||||||
|
|
@ -131,8 +134,8 @@ begin
|
||||||
openScope(c.tab); // scope for imported symbols
|
openScope(c.tab); // scope for imported symbols
|
||||||
SymTabAdd(c.tab, result);
|
SymTabAdd(c.tab, result);
|
||||||
if not isSystemFile then begin
|
if not isSystemFile then begin
|
||||||
importAllSymbols(c, magicsys.SystemModule);
|
|
||||||
SymTabAdd(c.tab, magicsys.SystemModule); // import the "System" identifier
|
SymTabAdd(c.tab, magicsys.SystemModule); // import the "System" identifier
|
||||||
|
importAllSymbols(c, magicsys.SystemModule);
|
||||||
SymTabAdd(c.tab, newIsMainModuleSym(result, isMainFile));
|
SymTabAdd(c.tab, newIsMainModuleSym(result, isMainFile));
|
||||||
end
|
end
|
||||||
else begin
|
else begin
|
||||||
|
|
@ -142,7 +145,6 @@ begin
|
||||||
end;
|
end;
|
||||||
{@discard} semModule(c, ast);
|
{@discard} semModule(c, ast);
|
||||||
rawCloseScope(c.tab); // imported symbols; don't check for unused ones!
|
rawCloseScope(c.tab); // imported symbols; don't check for unused ones!
|
||||||
// XXX: compile the generated generic procs!
|
|
||||||
msgCompiled(result.name.s);
|
msgCompiled(result.name.s);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
@ -161,7 +163,7 @@ var
|
||||||
|
|
||||||
procedure addDependencyAux(importing, imported: PSym);
|
procedure addDependencyAux(importing, imported: PSym);
|
||||||
begin
|
begin
|
||||||
appRopeFormat(gDotGraph, '$1 -> $2;$n', [toRope(importing.name.s),
|
appf(gDotGraph, '$1 -> $2;$n', [toRope(importing.name.s),
|
||||||
toRope(imported.name.s)]);
|
toRope(imported.name.s)]);
|
||||||
// s1 -> s2_4 [label="[0-9]"];
|
// s1 -> s2_4 [label="[0-9]"];
|
||||||
end;
|
end;
|
||||||
|
|
@ -193,7 +195,7 @@ end;
|
||||||
procedure generateDot(const project: string);
|
procedure generateDot(const project: string);
|
||||||
begin
|
begin
|
||||||
writeRope(
|
writeRope(
|
||||||
ropeFormat('digraph $1 {$n$2}$n', [
|
ropef('digraph $1 {$n$2}$n', [
|
||||||
toRope(changeFileExt(extractFileName(project), '')), gDotGraph]),
|
toRope(changeFileExt(extractFileName(project), '')), gDotGraph]),
|
||||||
changeFileExt(project, 'dot') );
|
changeFileExt(project, 'dot') );
|
||||||
end;
|
end;
|
||||||
|
|
@ -257,6 +259,14 @@ begin
|
||||||
extccomp.CallCCompiler(changeFileExt(filename, ''));
|
extccomp.CallCCompiler(changeFileExt(filename, ''));
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure CommandCompileToEcmaScript(const filename: string);
|
||||||
|
begin
|
||||||
|
include(gGlobalOptions, optSafeCode);
|
||||||
|
setTarget(osEcmaScript, cpuEcmaScript);
|
||||||
|
initDefines();
|
||||||
|
compileProject(filename, EcmasBackend(nil, nil, filename));
|
||||||
|
end;
|
||||||
|
|
||||||
// --------------------------------------------------------------------------
|
// --------------------------------------------------------------------------
|
||||||
|
|
||||||
procedure exSymbols(n: PNode);
|
procedure exSymbols(n: PNode);
|
||||||
|
|
@ -279,7 +289,7 @@ begin
|
||||||
for i := 0 to sonsLen(n)-1 do begin
|
for i := 0 to sonsLen(n)-1 do begin
|
||||||
exSymbol(n.sons[i].sons[0]);
|
exSymbol(n.sons[i].sons[0]);
|
||||||
if (n.sons[i].sons[2] <> nil) and
|
if (n.sons[i].sons[2] <> nil) and
|
||||||
(n.sons[i].sons[2].kind in [nkRecordTy, nkObjectTy]) then
|
(n.sons[i].sons[2].kind = nkObjectTy) then
|
||||||
fixRecordDef(n.sons[i].sons[2])
|
fixRecordDef(n.sons[i].sons[2])
|
||||||
end
|
end
|
||||||
end;
|
end;
|
||||||
|
|
@ -406,6 +416,11 @@ begin
|
||||||
wantFile(filename);
|
wantFile(filename);
|
||||||
CommandCompileToC(filename);
|
CommandCompileToC(filename);
|
||||||
end;
|
end;
|
||||||
|
wCompileToEcmaScript: begin
|
||||||
|
gCmd := cmdCompileToEcmaScript;
|
||||||
|
wantFile(filename);
|
||||||
|
CommandCompileToEcmaScript(filename);
|
||||||
|
end;
|
||||||
wPretty: begin
|
wPretty: begin
|
||||||
// compile means compileToC currently
|
// compile means compileToC currently
|
||||||
gCmd := cmdPretty;
|
gCmd := cmdPretty;
|
||||||
|
|
|
||||||
73
nim/msgs.pas
73
nim/msgs.pas
|
|
@ -74,10 +74,6 @@ type
|
||||||
errTokenExpected,
|
errTokenExpected,
|
||||||
errStringAfterIncludeExpected,
|
errStringAfterIncludeExpected,
|
||||||
errRecursiveInclude,
|
errRecursiveInclude,
|
||||||
errAtIfExpected,
|
|
||||||
errAtIfExpectedBeforeElse,
|
|
||||||
errAtIfExpectedBeforeElif,
|
|
||||||
errAtEndExpected,
|
|
||||||
errOnOrOffExpected,
|
errOnOrOffExpected,
|
||||||
errNoneSpeedOrSizeExpected,
|
errNoneSpeedOrSizeExpected,
|
||||||
errInvalidPragma,
|
errInvalidPragma,
|
||||||
|
|
@ -186,7 +182,7 @@ type
|
||||||
errSizeTooBig,
|
errSizeTooBig,
|
||||||
errSetTooBig,
|
errSetTooBig,
|
||||||
errBaseTypeMustBeOrdinal,
|
errBaseTypeMustBeOrdinal,
|
||||||
errInheritanceOnlyWithObjects,
|
errInheritanceOnlyWithNonFinalObjects,
|
||||||
errInheritanceOnlyWithEnums,
|
errInheritanceOnlyWithEnums,
|
||||||
errIllegalRecursionInTypeX,
|
errIllegalRecursionInTypeX,
|
||||||
errCannotInstantiateX,
|
errCannotInstantiateX,
|
||||||
|
|
@ -267,6 +263,20 @@ type
|
||||||
errWhitespaceExpected,
|
errWhitespaceExpected,
|
||||||
errXisNoValidIndexFile,
|
errXisNoValidIndexFile,
|
||||||
errCannotRenderX,
|
errCannotRenderX,
|
||||||
|
errVarVarTypeNotAllowed,
|
||||||
|
errIsExpectsTwoArguments,
|
||||||
|
errIsExpectsObjectTypes,
|
||||||
|
errXcanNeverBeOfThisSubtype,
|
||||||
|
errTooManyIterations,
|
||||||
|
errCannotInterpretNodeX,
|
||||||
|
errFieldXNotFound,
|
||||||
|
errInvalidConversionFromTypeX,
|
||||||
|
errAssertionFailed,
|
||||||
|
errCannotGenerateCodeForX,
|
||||||
|
errXNeedsReturnType,
|
||||||
|
errXRequiresOneArgument,
|
||||||
|
errUnhandledExceptionX,
|
||||||
|
errCyclicTree,
|
||||||
errUser,
|
errUser,
|
||||||
warnCannotOpenFile,
|
warnCannotOpenFile,
|
||||||
warnOctalEscape,
|
warnOctalEscape,
|
||||||
|
|
@ -291,6 +301,8 @@ type
|
||||||
hintMo2FileInvalid,
|
hintMo2FileInvalid,
|
||||||
hintModuleHasChanged,
|
hintModuleHasChanged,
|
||||||
hintCannotOpenMo2File,
|
hintCannotOpenMo2File,
|
||||||
|
hintQuitCalled,
|
||||||
|
hintProcessing,
|
||||||
hintUser);
|
hintUser);
|
||||||
|
|
||||||
const
|
const
|
||||||
|
|
@ -310,7 +322,7 @@ const
|
||||||
'invalid token: $1',
|
'invalid token: $1',
|
||||||
'line too long',
|
'line too long',
|
||||||
'$1 is not a valid number',
|
'$1 is not a valid number',
|
||||||
'$1 is too large or too small',
|
'number $1 out of valid range',
|
||||||
'\n not allowed in character literal',
|
'\n not allowed in character literal',
|
||||||
'closing '']'' expected, but end of file reached',
|
'closing '']'' expected, but end of file reached',
|
||||||
'missing final ''',
|
'missing final ''',
|
||||||
|
|
@ -319,10 +331,6 @@ const
|
||||||
'''$1'' expected',
|
'''$1'' expected',
|
||||||
'string after ''include'' expected',
|
'string after ''include'' expected',
|
||||||
'recursive include file: ''$1''',
|
'recursive include file: ''$1''',
|
||||||
'''@if'' expected',
|
|
||||||
'''@if'' expected before ''@else''',
|
|
||||||
'''@if'' expected before ''@elif''',
|
|
||||||
'''@end'' expected',
|
|
||||||
'''on'' or ''off'' expected',
|
'''on'' or ''off'' expected',
|
||||||
'''none'', ''speed'' or ''size'' expected',
|
'''none'', ''speed'' or ''size'' expected',
|
||||||
'invalid pragma',
|
'invalid pragma',
|
||||||
|
|
@ -431,12 +439,12 @@ const
|
||||||
'computing the type''s size produced an overflow',
|
'computing the type''s size produced an overflow',
|
||||||
'set is too large',
|
'set is too large',
|
||||||
'base type of a set must be an ordinal',
|
'base type of a set must be an ordinal',
|
||||||
'inheritance only works with an object',
|
'inheritance only works non-final objects',
|
||||||
'inheritance only works with an enum',
|
'inheritance only works with an enum',
|
||||||
'illegal recursion in type ''$1''',
|
'illegal recursion in type ''$1''',
|
||||||
'cannot instantiate: ''$1''',
|
'cannot instantiate: ''$1''',
|
||||||
'expression has no address',
|
'expression has no address',
|
||||||
'to an out parameter a variable needs to be passed',
|
'for a ''var'' type a variable needs to be passed',
|
||||||
'type mismatch',
|
'type mismatch',
|
||||||
'type mismatch: got (',
|
'type mismatch: got (',
|
||||||
'but expected one of: ',
|
'but expected one of: ',
|
||||||
|
|
@ -512,6 +520,20 @@ const
|
||||||
'whitespace expected, got ''$1''',
|
'whitespace expected, got ''$1''',
|
||||||
'''$1'' is no valid index file',
|
'''$1'' is no valid index file',
|
||||||
'cannot render reStructuredText element ''$1''',
|
'cannot render reStructuredText element ''$1''',
|
||||||
|
'type ''var var'' is not allowed',
|
||||||
|
'''is'' expects two arguments',
|
||||||
|
'''is'' expects object types',
|
||||||
|
'''$1'' can never be of this subtype',
|
||||||
|
'interpretation requires too many iterations',
|
||||||
|
'cannot interpret node kind ''$1''',
|
||||||
|
'field ''$1'' cannot be found',
|
||||||
|
'invalid conversion from type ''$1''',
|
||||||
|
'assertion failed',
|
||||||
|
'cannot generate code for ''$1''',
|
||||||
|
'converter needs return type',
|
||||||
|
'converter requires one parameter',
|
||||||
|
'unhandled exception: $1',
|
||||||
|
'macro returned a cyclic abstract syntax tree',
|
||||||
'$1',
|
'$1',
|
||||||
'cannot open ''$1'' [CannotOpenFile]',
|
'cannot open ''$1'' [CannotOpenFile]',
|
||||||
'octal escape sequences do not exist; leading zero is ignored [OctalEscape]',
|
'octal escape sequences do not exist; leading zero is ignored [OctalEscape]',
|
||||||
|
|
@ -536,6 +558,8 @@ const
|
||||||
'mo2 file ''$1'' is invalid [Mo2FileInvalid]',
|
'mo2 file ''$1'' is invalid [Mo2FileInvalid]',
|
||||||
'module ''$1'' has been changed [ModuleHasChanged]',
|
'module ''$1'' has been changed [ModuleHasChanged]',
|
||||||
'mo2 file ''$1'' does not exist [CannotOpenMo2File]',
|
'mo2 file ''$1'' does not exist [CannotOpenMo2File]',
|
||||||
|
'quit() called [QuitCalled]',
|
||||||
|
'processing [Processing]',
|
||||||
'$1 [User]'
|
'$1 [User]'
|
||||||
);
|
);
|
||||||
const
|
const
|
||||||
|
|
@ -556,7 +580,7 @@ const
|
||||||
'User'
|
'User'
|
||||||
);
|
);
|
||||||
const
|
const
|
||||||
HintsToStr: array [0..9] of string = (
|
HintsToStr: array [0..11] of string = (
|
||||||
'Success',
|
'Success',
|
||||||
'LineTooLong',
|
'LineTooLong',
|
||||||
'XDeclaredButNotUsed',
|
'XDeclaredButNotUsed',
|
||||||
|
|
@ -566,6 +590,8 @@ const
|
||||||
'Mo2FileInvalid',
|
'Mo2FileInvalid',
|
||||||
'ModuleHasChanged',
|
'ModuleHasChanged',
|
||||||
'CannotOpenMo2File',
|
'CannotOpenMo2File',
|
||||||
|
'QuitCalled',
|
||||||
|
'Processing',
|
||||||
'User'
|
'User'
|
||||||
);
|
);
|
||||||
//[[[end]]]
|
//[[[end]]]
|
||||||
|
|
@ -593,12 +619,7 @@ type
|
||||||
fileIndex: int32;
|
fileIndex: int32;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
const
|
function UnknownLineInfo(): TLineInfo;
|
||||||
UnknownLineInfo: TLineInfo = (
|
|
||||||
line: -1;
|
|
||||||
col: -1;
|
|
||||||
fileIndex: -1;
|
|
||||||
);
|
|
||||||
|
|
||||||
var
|
var
|
||||||
gNotes: TNoteKinds = [low(TNoteKind)..high(TNoteKind)];
|
gNotes: TNoteKinds = [low(TNoteKind)..high(TNoteKind)];
|
||||||
|
|
@ -649,6 +670,13 @@ procedure popInfoContext;
|
||||||
|
|
||||||
implementation
|
implementation
|
||||||
|
|
||||||
|
function UnknownLineInfo(): TLineInfo;
|
||||||
|
begin
|
||||||
|
result.line := -1;
|
||||||
|
result.col := -1;
|
||||||
|
result.fileIndex := -1;
|
||||||
|
end;
|
||||||
|
|
||||||
{@ignore}
|
{@ignore}
|
||||||
var
|
var
|
||||||
filenames: array of string;
|
filenames: array of string;
|
||||||
|
|
@ -782,12 +810,13 @@ end;
|
||||||
procedure handleError(const msg: TMsgKind);
|
procedure handleError(const msg: TMsgKind);
|
||||||
begin
|
begin
|
||||||
if (msg >= fatalMin) and (msg <= fatalMax) then begin
|
if (msg >= fatalMin) and (msg <= fatalMax) then begin
|
||||||
assert(false); halt(1)
|
if optVerbose in gGlobalOptions then assert(false);
|
||||||
|
halt(1)
|
||||||
end;
|
end;
|
||||||
if (msg >= errMin) and (msg <= errMax) then begin
|
if (msg >= errMin) and (msg <= errMax) then begin
|
||||||
inc(gErrorCounter);
|
inc(gErrorCounter);
|
||||||
if gErrorCounter >= gErrorMax then begin
|
if gErrorCounter >= gErrorMax then begin
|
||||||
assert(false); // stack trace for debugging
|
if optVerbose in gGlobalOptions then assert(false);
|
||||||
halt(1) // one error stops the compiler
|
halt(1) // one error stops the compiler
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
@ -797,7 +826,7 @@ procedure writeContext;
|
||||||
var
|
var
|
||||||
i: int;
|
i: int;
|
||||||
begin
|
begin
|
||||||
for i := length(msgContext)-1 downto 0 do begin
|
for i := 0 to length(msgContext)-1 do begin
|
||||||
MessageOut(Format(posErrorFormat, [toFilename(msgContext[i]),
|
MessageOut(Format(posErrorFormat, [toFilename(msgContext[i]),
|
||||||
coordToStr(msgContext[i].line),
|
coordToStr(msgContext[i].line),
|
||||||
coordToStr(msgContext[i].col),
|
coordToStr(msgContext[i].col),
|
||||||
|
|
|
||||||
|
|
@ -101,7 +101,7 @@ var
|
||||||
|
|
||||||
procedure doEnd(var L: TLexer; tok: PToken);
|
procedure doEnd(var L: TLexer; tok: PToken);
|
||||||
begin
|
begin
|
||||||
if high(condStack) < 0 then lexMessage(L, errAtIfExpected);
|
if high(condStack) < 0 then lexMessage(L, errTokenExpected, '@if');
|
||||||
ppGetTok(L, tok); // skip 'end'
|
ppGetTok(L, tok); // skip 'end'
|
||||||
setLength(condStack, high(condStack))
|
setLength(condStack, high(condStack))
|
||||||
end;
|
end;
|
||||||
|
|
@ -114,7 +114,7 @@ procedure jumpToDirective(var L: TLexer; tok: PToken; dest: TJumpDest); forward;
|
||||||
procedure doElse(var L: TLexer; tok: PToken);
|
procedure doElse(var L: TLexer; tok: PToken);
|
||||||
begin
|
begin
|
||||||
if high(condStack) < 0 then
|
if high(condStack) < 0 then
|
||||||
lexMessage(L, errAtIfExpectedBeforeElse);
|
lexMessage(L, errTokenExpected, '@if');
|
||||||
ppGetTok(L, tok);
|
ppGetTok(L, tok);
|
||||||
if tok.tokType = tkColon then ppGetTok(L, tok);
|
if tok.tokType = tkColon then ppGetTok(L, tok);
|
||||||
if condStack[high(condStack)] then
|
if condStack[high(condStack)] then
|
||||||
|
|
@ -126,7 +126,7 @@ var
|
||||||
res: bool;
|
res: bool;
|
||||||
begin
|
begin
|
||||||
if high(condStack) < 0 then
|
if high(condStack) < 0 then
|
||||||
lexMessage(L, errAtIfExpectedBeforeElif);
|
lexMessage(L, errTokenExpected, '@if');
|
||||||
res := EvalppIf(L, tok);
|
res := EvalppIf(L, tok);
|
||||||
if condStack[high(condStack)] or not res then
|
if condStack[high(condStack)] or not res then
|
||||||
jumpToDirective(L, tok, jdElseEndif)
|
jumpToDirective(L, tok, jdElseEndif)
|
||||||
|
|
@ -168,7 +168,7 @@ begin
|
||||||
ppGetTok(L, tok)
|
ppGetTok(L, tok)
|
||||||
end
|
end
|
||||||
else if tok.tokType = tkEof then
|
else if tok.tokType = tkEof then
|
||||||
lexMessage(L, errAtEndExpected)
|
lexMessage(L, errTokenExpected, '@end')
|
||||||
else
|
else
|
||||||
ppGetTok(L, tok)
|
ppGetTok(L, tok)
|
||||||
end
|
end
|
||||||
|
|
@ -303,7 +303,7 @@ begin
|
||||||
while tok.tokType <> tkEof do
|
while tok.tokType <> tkEof do
|
||||||
parseAssignment(L, tok);
|
parseAssignment(L, tok);
|
||||||
if length(condStack) > 0 then
|
if length(condStack) > 0 then
|
||||||
lexMessage(L, errAtEndExpected);
|
lexMessage(L, errTokenExpected, '@end');
|
||||||
closeLexer(L)
|
closeLexer(L)
|
||||||
end
|
end
|
||||||
end;
|
end;
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@
|
||||||
// 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.
|
||||||
//
|
//
|
||||||
program nim;
|
program nimrod;
|
||||||
|
|
||||||
{$include 'config.inc'}
|
{$include 'config.inc'}
|
||||||
{@ignore}
|
{@ignore}
|
||||||
|
|
@ -18,39 +18,37 @@ program nim;
|
||||||
uses
|
uses
|
||||||
nsystem,
|
nsystem,
|
||||||
charsets, sysutils, commands, scanner, condsyms, options, msgs, nversion,
|
charsets, sysutils, commands, scanner, condsyms, options, msgs, nversion,
|
||||||
nimconf, ropes, extccomp, strutils, nos, platform, main;
|
nimconf, ropes, extccomp, strutils, nos, platform, main, parseopt;
|
||||||
|
|
||||||
var
|
var
|
||||||
arguments: string = ''; // the arguments to be passed to the program that
|
arguments: string = ''; // the arguments to be passed to the program that
|
||||||
// should be run
|
// should be run
|
||||||
|
cmdLineInfo: TLineInfo;
|
||||||
|
|
||||||
function ProcessCmdLine(pass: TCmdLinePass): string;
|
procedure ProcessCmdLine(pass: TCmdLinePass; var command, filename: string);
|
||||||
var
|
var
|
||||||
i, paramCounter: int;
|
p: TOptParser;
|
||||||
param: string;
|
|
||||||
begin
|
begin
|
||||||
i := 1;
|
p := parseopt.init();
|
||||||
result := '';
|
while true do begin
|
||||||
paramCounter := paramCount();
|
parseopt.next(p);
|
||||||
while i <= paramCounter do begin
|
case p.kind of
|
||||||
param := ParamStr(i);
|
cmdEnd: break;
|
||||||
if param[strStart] = '-' then begin
|
cmdLongOption, cmdShortOption:
|
||||||
commands.ProcessCommand(param, pass);
|
ProcessSwitch(p.key, p.val, pass, cmdLineInfo);
|
||||||
|
cmdArgument: begin
|
||||||
|
if command = '' then command := p.key
|
||||||
|
else if filename = '' then begin
|
||||||
|
filename := unixToNativePath(p.key);
|
||||||
|
// BUGFIX for portable build scripts
|
||||||
|
break
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
else if i > 1 then begin
|
|
||||||
result := unixToNativePath(param); // BUGFIX for portable build scripts
|
|
||||||
options.compilerArgs := i;
|
|
||||||
break // do not process the arguments
|
|
||||||
end;
|
end;
|
||||||
Inc(i)
|
|
||||||
end;
|
|
||||||
inc(i); // skip program file
|
|
||||||
// collect the arguments:
|
// collect the arguments:
|
||||||
if pass = passCmd2 then begin
|
if pass = passCmd2 then begin
|
||||||
while i <= paramCounter do begin
|
arguments := getRestOfCommandLine(p);
|
||||||
arguments := arguments + ' ' +{&} paramStr(i);
|
|
||||||
inc(i)
|
|
||||||
end;
|
|
||||||
if not (optRun in gGlobalOptions) and (arguments <> '') then
|
if not (optRun in gGlobalOptions) and (arguments <> '') then
|
||||||
rawMessage(errArgsNeedRunOption);
|
rawMessage(errArgsNeedRunOption);
|
||||||
end
|
end
|
||||||
|
|
@ -58,42 +56,36 @@ end;
|
||||||
|
|
||||||
procedure HandleCmdLine;
|
procedure HandleCmdLine;
|
||||||
var
|
var
|
||||||
inp: string;
|
command, filename: string;
|
||||||
begin
|
begin
|
||||||
if paramCount() = 0 then
|
if paramCount() = 0 then
|
||||||
writeCommandLineUsage()
|
writeCommandLineUsage()
|
||||||
else begin
|
else begin
|
||||||
// Process command line arguments:
|
// Process command line arguments:
|
||||||
inp := ProcessCmdLine(passCmd1);
|
command := '';
|
||||||
if inp <> '' then begin
|
filename := '';
|
||||||
|
ProcessCmdLine(passCmd1, command, filename);
|
||||||
|
if filename <> '' then begin
|
||||||
if gCmd = cmdInterpret then DefineSymbol('interpreting');
|
if gCmd = cmdInterpret then DefineSymbol('interpreting');
|
||||||
nimconf.LoadConfig(inp); // load the right config file
|
nimconf.LoadConfig(filename); // load the right config file
|
||||||
// now process command line arguments again, because some options in the
|
// now process command line arguments again, because some options in the
|
||||||
// command line can overwite the config file's settings
|
// command line can overwite the config file's settings
|
||||||
extccomp.initVars();
|
extccomp.initVars();
|
||||||
inp := ProcessCmdLine(passCmd2);
|
command := '';
|
||||||
|
filename := '';
|
||||||
|
ProcessCmdLine(passCmd2, command, filename);
|
||||||
end;
|
end;
|
||||||
MainCommand(paramStr(1), inp);
|
MainCommand(command, filename);
|
||||||
if (gCmd <> cmdInterpret) and (msgs.gErrorCounter = 0) then
|
if (gCmd <> cmdInterpret) and (msgs.gErrorCounter = 0) then
|
||||||
rawMessage(hintSuccess);
|
rawMessage(hintSuccess);
|
||||||
if optRun in gGlobalOptions then
|
if optRun in gGlobalOptions then
|
||||||
execExternalProgram(changeFileExt(inp, '') +{&} arguments)
|
execExternalProgram(changeFileExt(filename, '') +{&} ' ' +{&} arguments)
|
||||||
end
|
end
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{@ignore}
|
|
||||||
var
|
|
||||||
Saved8087CW: Word;
|
|
||||||
{@emit}
|
|
||||||
begin
|
begin
|
||||||
{@ignore}
|
cmdLineInfo := newLineInfo('command line', -1, -1);
|
||||||
Saved8087CW := Default8087CW;
|
|
||||||
Set8087CW($133f); // Disable all fpu exceptions
|
|
||||||
{@emit}
|
|
||||||
condsyms.InitDefines();
|
condsyms.InitDefines();
|
||||||
HandleCmdLine();
|
HandleCmdLine();
|
||||||
{@ignore}
|
|
||||||
Set8087CW(Saved8087CW);
|
|
||||||
{@emit}
|
|
||||||
halt(options.gExitcode);
|
halt(options.gExitcode);
|
||||||
end.
|
end.
|
||||||
|
|
|
||||||
|
|
@ -49,7 +49,7 @@ function inSet(s: PNode; const elem: PNode): Boolean;
|
||||||
var
|
var
|
||||||
i: int;
|
i: int;
|
||||||
begin
|
begin
|
||||||
assert(s.kind in [nkSetConstr, nkConstSetConstr]);
|
if s.kind <> nkCurly then InternalError(s.info, 'inSet');
|
||||||
for i := 0 to sonsLen(s)-1 do
|
for i := 0 to sonsLen(s)-1 do
|
||||||
if s.sons[i].kind = nkRange then begin
|
if s.sons[i].kind = nkRange then begin
|
||||||
if leValue(s.sons[i].sons[0], elem)
|
if leValue(s.sons[i].sons[0], elem)
|
||||||
|
|
@ -95,7 +95,7 @@ function SomeInSet(s: PNode; const a, b: PNode): Boolean;
|
||||||
var
|
var
|
||||||
i: int;
|
i: int;
|
||||||
begin
|
begin
|
||||||
assert(s.kind in [nkSetConstr, nkConstSetConstr]);
|
if s.kind <> nkCurly then InternalError(s.info, 'SomeInSet');
|
||||||
for i := 0 to sonsLen(s)-1 do
|
for i := 0 to sonsLen(s)-1 do
|
||||||
if s.sons[i].kind = nkRange then begin
|
if s.sons[i].kind = nkRange then begin
|
||||||
if leValue(s.sons[i].sons[0], b)
|
if leValue(s.sons[i].sons[0], b)
|
||||||
|
|
@ -142,7 +142,7 @@ var
|
||||||
begin
|
begin
|
||||||
elemType := settype.sons[0];
|
elemType := settype.sons[0];
|
||||||
first := firstOrd(elemType);
|
first := firstOrd(elemType);
|
||||||
result := newNode(nkConstSetConstr);
|
result := newNode(nkCurly);
|
||||||
result.typ := settype;
|
result.typ := settype;
|
||||||
result.info := info;
|
result.info := info;
|
||||||
|
|
||||||
|
|
@ -244,7 +244,7 @@ function SetHasRange(s: PNode): Boolean;
|
||||||
var
|
var
|
||||||
i: int;
|
i: int;
|
||||||
begin
|
begin
|
||||||
assert(s.kind in [nkSetConstr, nkConstSetConstr]);
|
if s.kind <> nkCurly then InternalError(s.info, 'SetHasRange');
|
||||||
for i := 0 to sonsLen(s)-1 do
|
for i := 0 to sonsLen(s)-1 do
|
||||||
if s.sons[i].kind = nkRange then begin
|
if s.sons[i].kind = nkRange then begin
|
||||||
result := true; exit
|
result := true; exit
|
||||||
|
|
|
||||||
35
nim/nos.pas
35
nim/nos.pas
|
|
@ -22,8 +22,8 @@ uses
|
||||||
{$ifdef mswindows}
|
{$ifdef mswindows}
|
||||||
windows,
|
windows,
|
||||||
{$else}
|
{$else}
|
||||||
unix,
|
|
||||||
dos,
|
dos,
|
||||||
|
unix,
|
||||||
{$endif}
|
{$endif}
|
||||||
strutils,
|
strutils,
|
||||||
nsystem;
|
nsystem;
|
||||||
|
|
@ -83,6 +83,14 @@ function sameFile(const path1, path2: string): boolean;
|
||||||
|
|
||||||
implementation
|
implementation
|
||||||
|
|
||||||
|
function UnixToNativePath(const path: string): string;
|
||||||
|
begin
|
||||||
|
if dirSep <> '/' then
|
||||||
|
result := replaceStr(path, '/', dirSep)
|
||||||
|
else
|
||||||
|
result := path;
|
||||||
|
end;
|
||||||
|
|
||||||
function expandFilename(filename: string): string;
|
function expandFilename(filename: string): string;
|
||||||
begin
|
begin
|
||||||
result := sysutils.expandFilename(filename)
|
result := sysutils.expandFilename(filename)
|
||||||
|
|
@ -90,16 +98,8 @@ end;
|
||||||
|
|
||||||
function sameFile(const path1, path2: string): boolean;
|
function sameFile(const path1, path2: string): boolean;
|
||||||
begin
|
begin
|
||||||
result := cmpIgnoreCase(expandFilename(path1),
|
result := cmpIgnoreCase(expandFilename(UnixToNativePath(path1)),
|
||||||
expandFilename(path2)) = 0;
|
expandFilename(UnixToNativePath(path2))) = 0;
|
||||||
end;
|
|
||||||
|
|
||||||
function UnixToNativePath(const path: string): string;
|
|
||||||
begin
|
|
||||||
if dirSep <> '/' then
|
|
||||||
result := replaceStr(path, '/', dirSep)
|
|
||||||
else
|
|
||||||
result := path;
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure createDir(dir: string);
|
procedure createDir(dir: string);
|
||||||
|
|
@ -417,8 +417,9 @@ begin
|
||||||
SI.hStdError := GetStdHandle(STD_ERROR_HANDLE);
|
SI.hStdError := GetStdHandle(STD_ERROR_HANDLE);
|
||||||
SI.hStdInput := GetStdHandle(STD_INPUT_HANDLE);
|
SI.hStdInput := GetStdHandle(STD_INPUT_HANDLE);
|
||||||
SI.hStdOutput := GetStdHandle(STD_OUTPUT_HANDLE);
|
SI.hStdOutput := GetStdHandle(STD_OUTPUT_HANDLE);
|
||||||
if not Windows.CreateProcess(nil, PChar(cmd), nil, nil, true,
|
if not Windows.CreateProcess(nil, PChar(cmd), nil, nil, false,
|
||||||
NORMAL_PRIORITY_CLASS, Windows.GetEnvironmentStrings(), nil, SI, ProcInfo)
|
NORMAL_PRIORITY_CLASS, nil {Windows.GetEnvironmentStrings()},
|
||||||
|
nil, SI, ProcInfo)
|
||||||
then
|
then
|
||||||
result := getLastError()
|
result := getLastError()
|
||||||
else begin
|
else begin
|
||||||
|
|
@ -434,6 +435,13 @@ begin
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
{$else}
|
||||||
|
{$ifdef windows}
|
||||||
|
function executeProcess(const cmd: string): int;
|
||||||
|
begin
|
||||||
|
result := dos.Exec(cmd, '')
|
||||||
|
end;
|
||||||
|
//C:\Eigenes\compiler\MinGW\bin;
|
||||||
{$else}
|
{$else}
|
||||||
// fpc has a portable function for this
|
// fpc has a portable function for this
|
||||||
function executeProcess(const cmd: string): int;
|
function executeProcess(const cmd: string): int;
|
||||||
|
|
@ -441,6 +449,7 @@ begin
|
||||||
result := shell(cmd);
|
result := shell(cmd);
|
||||||
end;
|
end;
|
||||||
{$endif}
|
{$endif}
|
||||||
|
{$endif}
|
||||||
|
|
||||||
{$ifdef windows}
|
{$ifdef windows}
|
||||||
type
|
type
|
||||||
|
|
|
||||||
|
|
@ -90,10 +90,11 @@ type
|
||||||
TAddress = longint;
|
TAddress = longint;
|
||||||
{$endif}
|
{$endif}
|
||||||
|
|
||||||
|
var
|
||||||
|
NaN: float;
|
||||||
|
inf: float;
|
||||||
|
NegInf: float;
|
||||||
{$ifdef fpc}
|
{$ifdef fpc}
|
||||||
const
|
|
||||||
inf = math.Infinity;
|
|
||||||
NegInf = -inf;
|
|
||||||
{$else}
|
{$else}
|
||||||
{$ifopt Q+}
|
{$ifopt Q+}
|
||||||
{$define Q_on}
|
{$define Q_on}
|
||||||
|
|
@ -150,6 +151,10 @@ function shlU(a, b: biggestInt): biggestInt;
|
||||||
function shrU(a, b: biggestInt): biggestInt;
|
function shrU(a, b: biggestInt): biggestInt;
|
||||||
function ltU(a, b: biggestInt): bool;
|
function ltU(a, b: biggestInt): bool;
|
||||||
function leU(a, b: biggestInt): bool;
|
function leU(a, b: biggestInt): bool;
|
||||||
|
|
||||||
|
function toU8(a: biggestInt): byte;
|
||||||
|
function toU32(a: biggestInt): int32;
|
||||||
|
function ze64(a: byte): biggestInt;
|
||||||
{@emit}
|
{@emit}
|
||||||
|
|
||||||
function alloc(size: int): Pointer;
|
function alloc(size: int): Pointer;
|
||||||
|
|
@ -257,6 +262,23 @@ function leU(a, b: biggestInt): bool;
|
||||||
begin
|
begin
|
||||||
result := biggestUInt(a) < biggestUInt(b);
|
result := biggestUInt(a) < biggestUInt(b);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function toU8(a: biggestInt): byte;
|
||||||
|
begin
|
||||||
|
assert(a >= 0);
|
||||||
|
assert(a <= 255);
|
||||||
|
result := a;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function toU32(a: biggestInt): int32;
|
||||||
|
begin
|
||||||
|
result := int32(a and $ffffffff);
|
||||||
|
end;
|
||||||
|
|
||||||
|
function ze64(a: byte): biggestInt;
|
||||||
|
begin
|
||||||
|
result := a
|
||||||
|
end;
|
||||||
{@emit}
|
{@emit}
|
||||||
|
|
||||||
procedure addChar(var s: string; c: Char);
|
procedure addChar(var s: string; c: Char);
|
||||||
|
|
@ -486,4 +508,21 @@ end;
|
||||||
|
|
||||||
{$ifdef I_on} {$undef I_on} {$I+} {$endif}
|
{$ifdef I_on} {$undef I_on} {$I+} {$endif}
|
||||||
|
|
||||||
|
{$ifopt R+} {$R-,Q-} {$define R_on} {$endif}
|
||||||
|
var
|
||||||
|
zero: float;
|
||||||
|
Saved8087CW: Word;
|
||||||
|
initialization
|
||||||
|
Saved8087CW := Default8087CW;
|
||||||
|
Set8087CW($133f); // Disable all fpu exceptions
|
||||||
|
|
||||||
|
zero := 0.0;
|
||||||
|
NaN := 0.0 / zero;
|
||||||
|
inf := 1.0 / zero;
|
||||||
|
NegInf := -inf;
|
||||||
|
finalization
|
||||||
|
Set8087CW(Saved8087CW);
|
||||||
|
{$ifdef R_on}
|
||||||
|
{$R+,Q+}
|
||||||
|
{$endif}
|
||||||
end.
|
end.
|
||||||
|
|
|
||||||
|
|
@ -18,22 +18,32 @@ interface
|
||||||
uses
|
uses
|
||||||
strutils;
|
strutils;
|
||||||
|
|
||||||
|
// the Pascal version number gets a little star ('*'), the Nimrod version
|
||||||
|
// does not! This helps distinguishing the different builds.
|
||||||
|
{@ignore}
|
||||||
|
const
|
||||||
|
VersionStar = '*'+'';
|
||||||
|
{@emit
|
||||||
|
const
|
||||||
|
VersionStar = '';
|
||||||
|
}
|
||||||
|
|
||||||
const
|
const
|
||||||
MaxSetElements = 1 shl 16; // (2^16) to support unicode character sets?
|
MaxSetElements = 1 shl 16; // (2^16) to support unicode character sets?
|
||||||
defaultAsmMarkerSymbol = '!';
|
defaultAsmMarkerSymbol = '!';
|
||||||
|
|
||||||
//[[[cog
|
//[[[cog
|
||||||
//from koch import NIMROD_VERSION
|
//from koch import NIMROD_VERSION
|
||||||
//cog.outl("VersionAsString = '%s';" % NIMROD_VERSION)
|
//cog.outl("VersionAsString = '%s'+VersionStar;" % NIMROD_VERSION)
|
||||||
//ver = NIMROD_VERSION.split('.')
|
//ver = NIMROD_VERSION.split('.')
|
||||||
//cog.outl('VersionMajor = %s;' % ver[0])
|
//cog.outl('VersionMajor = %s;' % ver[0])
|
||||||
//cog.outl('VersionMinor = %s;' % ver[1])
|
//cog.outl('VersionMinor = %s;' % ver[1])
|
||||||
//cog.outl('VersionPatch = %s;' % ver[2])
|
//cog.outl('VersionPatch = %s;' % ver[2])
|
||||||
//]]]
|
//]]]
|
||||||
VersionAsString = '0.5.1';
|
VersionAsString = '0.6.0'+VersionStar;
|
||||||
VersionMajor = 0;
|
VersionMajor = 0;
|
||||||
VersionMinor = 5;
|
VersionMinor = 6;
|
||||||
VersionPatch = 1;
|
VersionPatch = 0;
|
||||||
//[[[[end]]]]
|
//[[[[end]]]]
|
||||||
|
|
||||||
implementation
|
implementation
|
||||||
|
|
|
||||||
34
nim/optast.pas
Normal file
34
nim/optast.pas
Normal file
|
|
@ -0,0 +1,34 @@
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// The Nimrod Compiler
|
||||||
|
// (c) Copyright 2008 Andreas Rumpf
|
||||||
|
//
|
||||||
|
// See the file "copying.txt", included in this
|
||||||
|
// distribution, for details about the copyright.
|
||||||
|
//
|
||||||
|
|
||||||
|
unit optast;
|
||||||
|
|
||||||
|
// Optimizations that can be done by AST transformations. The code generators
|
||||||
|
// should work without the optimizer. The optimizer does the following:
|
||||||
|
|
||||||
|
// - cross-module constant merging
|
||||||
|
// - cross-module generic merging
|
||||||
|
// - lowers set operations to bit operations
|
||||||
|
// - inlining of procs
|
||||||
|
// - ``s == ""`` --> ``len(s) == 0``
|
||||||
|
// - optimization of ``&`` string operator
|
||||||
|
|
||||||
|
interface
|
||||||
|
|
||||||
|
{$include 'config.inc'}
|
||||||
|
|
||||||
|
uses
|
||||||
|
nsystem, ast, astalgo, strutils, hashes, trees, treetab, platform, magicsys,
|
||||||
|
options, msgs, crc, idents, lists, types, ropes, nmath, wordrecg, rnimsyn;
|
||||||
|
|
||||||
|
implementation
|
||||||
|
|
||||||
|
|
||||||
|
end.
|
||||||
|
|
||||||
|
|
@ -13,12 +13,14 @@ interface
|
||||||
{$include 'config.inc'}
|
{$include 'config.inc'}
|
||||||
|
|
||||||
uses
|
uses
|
||||||
nsystem, nos, lists, strutils;
|
nsystem, nos, lists, strutils, strtabs;
|
||||||
|
|
||||||
type
|
type
|
||||||
// please make sure we have under 32 options
|
// please make sure we have under 32 options
|
||||||
// (improves code efficiency a lot!)
|
// (improves code efficiency a lot!)
|
||||||
TOption = (optNone, optRangeCheck,
|
TOption = (optNone,
|
||||||
|
optObjCheck,
|
||||||
|
optFieldCheck, optRangeCheck,
|
||||||
optBoundsCheck, optOverflowCheck, optNilCheck, optAssert, optLineDir,
|
optBoundsCheck, optOverflowCheck, optNilCheck, optAssert, optLineDir,
|
||||||
optWarns, optHints,
|
optWarns, optHints,
|
||||||
optOptimizeSpeed,
|
optOptimizeSpeed,
|
||||||
|
|
@ -56,6 +58,7 @@ type
|
||||||
cmdNone,
|
cmdNone,
|
||||||
cmdCompileToC,
|
cmdCompileToC,
|
||||||
cmdCompileToCpp,
|
cmdCompileToCpp,
|
||||||
|
cmdCompileToEcmaScript,
|
||||||
cmdInterpret,
|
cmdInterpret,
|
||||||
cmdPretty,
|
cmdPretty,
|
||||||
cmdDoc,
|
cmdDoc,
|
||||||
|
|
@ -69,32 +72,27 @@ type
|
||||||
cmdDebugTrans, // debug a transformation pass
|
cmdDebugTrans, // debug a transformation pass
|
||||||
cmdRst2html // convert a reStructuredText file to HTML
|
cmdRst2html // convert a reStructuredText file to HTML
|
||||||
);
|
);
|
||||||
|
TStringSeq = array of string;
|
||||||
TNumericalBase = (base10, // base10 is listed as the first element,
|
|
||||||
// so that it is the correct default value
|
|
||||||
base2,
|
|
||||||
base8,
|
|
||||||
base16);
|
|
||||||
|
|
||||||
|
|
||||||
const
|
const
|
||||||
ChecksOptions = {@set}[optRangeCheck, optNilCheck, optOverflowCheck,
|
ChecksOptions = {@set}[optObjCheck, optFieldCheck, optRangeCheck,
|
||||||
optBoundsCheck, optAssert];
|
optNilCheck, optOverflowCheck, optBoundsCheck,
|
||||||
|
optAssert];
|
||||||
optionToStr: array [TOption] of string = (
|
optionToStr: array [TOption] of string = (
|
||||||
'optNone', 'optRangeCheck',
|
'optNone', 'optObjCheck', 'optFieldCheck', 'optRangeCheck',
|
||||||
'optBoundsCheck', 'optOverflowCheck', 'optNilCheck', 'optAssert',
|
'optBoundsCheck', 'optOverflowCheck', 'optNilCheck', 'optAssert',
|
||||||
'optLineDir', 'optWarns', 'optHints', 'optOptimizeSpeed',
|
'optLineDir', 'optWarns', 'optHints', 'optOptimizeSpeed',
|
||||||
'optOptimizeSize', 'optStackTrace', 'optLineTrace', 'optEmdb',
|
'optOptimizeSize', 'optStackTrace', 'optLineTrace', 'optEmdb',
|
||||||
'optByRef', 'optCheckpoints'
|
'optByRef', 'optCheckpoints'
|
||||||
);
|
);
|
||||||
var
|
var
|
||||||
gOptions: TOptions = {@set}[optRangeCheck, optBoundsCheck, optOverflowCheck,
|
gOptions: TOptions = {@set}[optObjCheck, optFieldCheck, optRangeCheck,
|
||||||
|
optBoundsCheck, optOverflowCheck,
|
||||||
optAssert, optWarns, optHints, optLineDir,
|
optAssert, optWarns, optHints, optLineDir,
|
||||||
optStackTrace, optLineTrace];
|
optStackTrace, optLineTrace];
|
||||||
|
|
||||||
gGlobalOptions: TGlobalOptions = {@set}[optRefcGC];
|
gGlobalOptions: TGlobalOptions = {@set}[optRefcGC];
|
||||||
|
|
||||||
compilerArgs: int;
|
|
||||||
gExitcode: Byte;
|
gExitcode: Byte;
|
||||||
searchPaths: TLinkedList;
|
searchPaths: TLinkedList;
|
||||||
outFile: string = '';
|
outFile: string = '';
|
||||||
|
|
@ -124,22 +122,15 @@ function getPrefixDir: string;
|
||||||
// gets the application directory
|
// gets the application directory
|
||||||
|
|
||||||
// additional configuration variables:
|
// additional configuration variables:
|
||||||
type
|
|
||||||
TPair = record
|
|
||||||
key, val: string;
|
|
||||||
end;
|
|
||||||
TPairs = array of TPair;
|
|
||||||
|
|
||||||
TStringSeq = array of string;
|
|
||||||
var
|
var
|
||||||
gConfigVars: TPairs = {@ignore} nil {@emit []};
|
gConfigVars: PStringTable;
|
||||||
libpath: string = '';
|
libpath: string = '';
|
||||||
gKeepComments: boolean = true; // whether the parser needs to keep comments
|
gKeepComments: boolean = true; // whether the parser needs to keep comments
|
||||||
gImplicitMods: TStringSeq = {@ignore} nil {@emit []};
|
gImplicitMods: TStringSeq = {@ignore} nil {@emit []};
|
||||||
// modules that are to be implicitly imported
|
// modules that are to be implicitly imported
|
||||||
|
|
||||||
procedure setConfigVar(const key, val: string);
|
|
||||||
function getConfigVar(const key: string): string;
|
function getConfigVar(const key: string): string;
|
||||||
|
procedure setConfigVar(const key, val: string);
|
||||||
|
|
||||||
procedure addImplicitMod(const filename: string);
|
procedure addImplicitMod(const filename: string);
|
||||||
|
|
||||||
|
|
@ -149,6 +140,16 @@ function binaryStrSearch(const x: array of string; const y: string): int;
|
||||||
|
|
||||||
implementation
|
implementation
|
||||||
|
|
||||||
|
function getConfigVar(const key: string): string;
|
||||||
|
begin
|
||||||
|
result := strtabs.get(gConfigVars, key);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure setConfigVar(const key, val: string);
|
||||||
|
begin
|
||||||
|
strtabs.put(gConfigVars, key, val);
|
||||||
|
end;
|
||||||
|
|
||||||
function getOutFile(const filename, ext: string): string;
|
function getOutFile(const filename, ext: string): string;
|
||||||
begin
|
begin
|
||||||
if options.outFile <> '' then result := options.outFile
|
if options.outFile <> '' then result := options.outFile
|
||||||
|
|
@ -172,38 +173,6 @@ begin
|
||||||
SplitPath(appdir, result, bin);
|
SplitPath(appdir, result, bin);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function getConfigIdx(const key: string): int;
|
|
||||||
var
|
|
||||||
i: int;
|
|
||||||
begin
|
|
||||||
for i := 0 to high(gConfigVars) do
|
|
||||||
if cmpIgnoreStyle(gConfigVars[i].key, key) = 0 then begin
|
|
||||||
result := i; exit end;
|
|
||||||
result := -1
|
|
||||||
end;
|
|
||||||
|
|
||||||
function getConfigVar(const key: string): string;
|
|
||||||
var
|
|
||||||
i: int;
|
|
||||||
begin
|
|
||||||
i := getConfigIdx(key);
|
|
||||||
if i >= 0 then result := gConfigVars[i].val
|
|
||||||
else result := ''
|
|
||||||
end;
|
|
||||||
|
|
||||||
procedure setConfigVar(const key, val: string);
|
|
||||||
var
|
|
||||||
i: int;
|
|
||||||
begin
|
|
||||||
i := getConfigIdx(key);
|
|
||||||
if i < 0 then begin
|
|
||||||
i := length(gConfigVars);
|
|
||||||
setLength(gConfigVars, i+1);
|
|
||||||
gConfigVars[i].key := key
|
|
||||||
end;
|
|
||||||
gConfigVars[i].val := val
|
|
||||||
end;
|
|
||||||
|
|
||||||
function toGeneratedFile(const path, ext: string): string;
|
function toGeneratedFile(const path, ext: string): string;
|
||||||
var
|
var
|
||||||
head, tail: string;
|
head, tail: string;
|
||||||
|
|
@ -261,4 +230,6 @@ begin
|
||||||
result := -1
|
result := -1
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
initialization
|
||||||
|
gConfigVars := newStringTable([], modeStyleInsensitive);
|
||||||
end.
|
end.
|
||||||
|
|
|
||||||
414
nim/parsecfg.pas
Normal file
414
nim/parsecfg.pas
Normal file
|
|
@ -0,0 +1,414 @@
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Nimrod's Runtime Library
|
||||||
|
// (c) Copyright 2008 Andreas Rumpf
|
||||||
|
//
|
||||||
|
// See the file "copying.txt", included in this
|
||||||
|
// distribution, for details about the copyright.
|
||||||
|
//
|
||||||
|
unit parsecfg;
|
||||||
|
|
||||||
|
// A HIGH-PERFORMANCE configuration file parser;
|
||||||
|
// the Nimrod version of this file will become part
|
||||||
|
// of the standard library.
|
||||||
|
|
||||||
|
interface
|
||||||
|
|
||||||
|
{$include 'config.inc'}
|
||||||
|
|
||||||
|
uses
|
||||||
|
charsets, nsystem, sysutils, hashes, strutils, lexbase;
|
||||||
|
|
||||||
|
type
|
||||||
|
TCfgEventKind = (
|
||||||
|
cfgEof, // end of file reached
|
||||||
|
cfgSectionStart, // a ``[section]`` has been parsed
|
||||||
|
cfgKeyValuePair, // a ``key=value`` pair has been detected
|
||||||
|
cfgOption, // a ``--key=value`` command line option
|
||||||
|
cfgError // an error ocurred during parsing; msg contains the
|
||||||
|
// error message
|
||||||
|
);
|
||||||
|
TCfgEvent = {@ignore} record
|
||||||
|
kind: TCfgEventKind;
|
||||||
|
section: string;
|
||||||
|
key, value: string;
|
||||||
|
msg: string;
|
||||||
|
end;
|
||||||
|
{@emit object(NObject)
|
||||||
|
case kind: TCfgEventKind of
|
||||||
|
cfgSection: (section: string);
|
||||||
|
cfgKeyValuePair, cfgOption: (key, value: string);
|
||||||
|
cfgError: (msg: string);
|
||||||
|
end;}
|
||||||
|
TTokKind = (tkInvalid, tkEof, // order is important here!
|
||||||
|
tkSymbol, tkEquals, tkColon,
|
||||||
|
tkBracketLe, tkBracketRi, tkDashDash
|
||||||
|
);
|
||||||
|
TToken = record // a token
|
||||||
|
kind: TTokKind; // the type of the token
|
||||||
|
literal: string; // the parsed (string) literal
|
||||||
|
end;
|
||||||
|
TParserState = (startState, commaState);
|
||||||
|
TCfgParser = object(TBaseLexer)
|
||||||
|
tok: TToken;
|
||||||
|
state: TParserState;
|
||||||
|
filename: string;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function Open(var c: TCfgParser; const filename: string): bool;
|
||||||
|
procedure OpenFromBuffer(var c: TCfgParser; const buf: string);
|
||||||
|
procedure Close(var c: TCfgParser);
|
||||||
|
|
||||||
|
function next(var c: TCfgParser): TCfgEvent;
|
||||||
|
|
||||||
|
function getColumn(const c: TCfgParser): int;
|
||||||
|
function getLine(const c: TCfgParser): int;
|
||||||
|
function getFilename(const c: TCfgParser): string;
|
||||||
|
|
||||||
|
implementation
|
||||||
|
|
||||||
|
const
|
||||||
|
SymChars: TCharSet = ['a'..'z', 'A'..'Z', '0'..'9', '_', #128..#255];
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
procedure rawGetTok(var c: TCfgParser; var tok: TToken); forward;
|
||||||
|
|
||||||
|
function open(var c: TCfgParser; const filename: string): bool;
|
||||||
|
begin
|
||||||
|
{@ignore}
|
||||||
|
FillChar(c, sizeof(c), 0); // work around Delphi/fpc bug
|
||||||
|
{@emit}
|
||||||
|
result := initBaseLexer(c, filename);
|
||||||
|
c.filename := filename;
|
||||||
|
c.state := startState;
|
||||||
|
c.tok.kind := tkInvalid;
|
||||||
|
c.tok.literal := '';
|
||||||
|
if result then rawGetTok(c, c.tok);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure openFromBuffer(var c: TCfgParser; const buf: string);
|
||||||
|
begin
|
||||||
|
{@ignore}
|
||||||
|
FillChar(c, sizeof(c), 0); // work around Delphi/fpc bug
|
||||||
|
{@emit}
|
||||||
|
initBaseLexerFromBuffer(c, buf);
|
||||||
|
c.filename := 'buffer';
|
||||||
|
c.state := startState;
|
||||||
|
c.tok.kind := tkInvalid;
|
||||||
|
c.tok.literal := '';
|
||||||
|
rawGetTok(c, c.tok);
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure close(var c: TCfgParser);
|
||||||
|
begin
|
||||||
|
deinitBaseLexer(c);
|
||||||
|
end;
|
||||||
|
|
||||||
|
function getColumn(const c: TCfgParser): int;
|
||||||
|
begin
|
||||||
|
result := getColNumber(c, c.bufPos)
|
||||||
|
end;
|
||||||
|
|
||||||
|
function getLine(const c: TCfgParser): int;
|
||||||
|
begin
|
||||||
|
result := c.linenumber
|
||||||
|
end;
|
||||||
|
|
||||||
|
function getFilename(const c: TCfgParser): string;
|
||||||
|
begin
|
||||||
|
result := c.filename
|
||||||
|
end;
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
procedure handleHexChar(var c: TCfgParser; var xi: int);
|
||||||
|
begin
|
||||||
|
case c.buf[c.bufpos] of
|
||||||
|
'0'..'9': begin
|
||||||
|
xi := (xi shl 4) or (ord(c.buf[c.bufpos]) - ord('0'));
|
||||||
|
inc(c.bufpos);
|
||||||
|
end;
|
||||||
|
'a'..'f': begin
|
||||||
|
xi := (xi shl 4) or (ord(c.buf[c.bufpos]) - ord('a') + 10);
|
||||||
|
inc(c.bufpos);
|
||||||
|
end;
|
||||||
|
'A'..'F': begin
|
||||||
|
xi := (xi shl 4) or (ord(c.buf[c.bufpos]) - ord('A') + 10);
|
||||||
|
inc(c.bufpos);
|
||||||
|
end;
|
||||||
|
else begin end // do nothing
|
||||||
|
end
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure handleDecChars(var c: TCfgParser; var xi: int);
|
||||||
|
begin
|
||||||
|
while c.buf[c.bufpos] in ['0'..'9'] do begin
|
||||||
|
xi := (xi * 10) + (ord(c.buf[c.bufpos]) - ord('0'));
|
||||||
|
inc(c.bufpos);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure getEscapedChar(var c: TCfgParser; var tok: TToken);
|
||||||
|
var
|
||||||
|
xi: int;
|
||||||
|
begin
|
||||||
|
inc(c.bufpos); // skip '\'
|
||||||
|
case c.buf[c.bufpos] of
|
||||||
|
'n', 'N': begin
|
||||||
|
tok.literal := tok.literal +{&} nl;
|
||||||
|
Inc(c.bufpos);
|
||||||
|
end;
|
||||||
|
'r', 'R', 'c', 'C': begin addChar(tok.literal, CR); Inc(c.bufpos); end;
|
||||||
|
'l', 'L': begin addChar(tok.literal, LF); Inc(c.bufpos); end;
|
||||||
|
'f', 'F': begin addChar(tok.literal, FF); inc(c.bufpos); end;
|
||||||
|
'e', 'E': begin addChar(tok.literal, ESC); Inc(c.bufpos); end;
|
||||||
|
'a', 'A': begin addChar(tok.literal, BEL); Inc(c.bufpos); end;
|
||||||
|
'b', 'B': begin addChar(tok.literal, BACKSPACE); Inc(c.bufpos); end;
|
||||||
|
'v', 'V': begin addChar(tok.literal, VT); Inc(c.bufpos); end;
|
||||||
|
't', 'T': begin addChar(tok.literal, Tabulator); Inc(c.bufpos); end;
|
||||||
|
'''', '"': begin addChar(tok.literal, c.buf[c.bufpos]); Inc(c.bufpos); end;
|
||||||
|
'\': begin addChar(tok.literal, '\'); Inc(c.bufpos) end;
|
||||||
|
'x', 'X': begin
|
||||||
|
inc(c.bufpos);
|
||||||
|
xi := 0;
|
||||||
|
handleHexChar(c, xi);
|
||||||
|
handleHexChar(c, xi);
|
||||||
|
addChar(tok.literal, Chr(xi));
|
||||||
|
end;
|
||||||
|
'0'..'9': begin
|
||||||
|
xi := 0;
|
||||||
|
handleDecChars(c, xi);
|
||||||
|
if (xi <= 255) then
|
||||||
|
addChar(tok.literal, Chr(xi))
|
||||||
|
else
|
||||||
|
tok.kind := tkInvalid
|
||||||
|
end
|
||||||
|
else tok.kind := tkInvalid
|
||||||
|
end
|
||||||
|
end;
|
||||||
|
|
||||||
|
function HandleCRLF(var c: TCfgParser; pos: int): int;
|
||||||
|
begin
|
||||||
|
case c.buf[pos] of
|
||||||
|
CR: result := lexbase.HandleCR(c, pos);
|
||||||
|
LF: result := lexbase.HandleLF(c, pos);
|
||||||
|
else result := pos
|
||||||
|
end
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure getString(var c: TCfgParser; var tok: TToken; rawMode: Boolean);
|
||||||
|
var
|
||||||
|
pos: int;
|
||||||
|
ch: Char;
|
||||||
|
buf: PChar;
|
||||||
|
begin
|
||||||
|
pos := c.bufPos + 1; // skip "
|
||||||
|
buf := c.buf; // put `buf` in a register
|
||||||
|
tok.kind := tkSymbol;
|
||||||
|
if (buf[pos] = '"') and (buf[pos+1] = '"') then begin
|
||||||
|
// long string literal:
|
||||||
|
inc(pos, 2); // skip ""
|
||||||
|
// skip leading newline:
|
||||||
|
pos := HandleCRLF(c, pos);
|
||||||
|
repeat
|
||||||
|
case buf[pos] of
|
||||||
|
'"': begin
|
||||||
|
if (buf[pos+1] = '"') and (buf[pos+2] = '"') then
|
||||||
|
break;
|
||||||
|
addChar(tok.literal, '"');
|
||||||
|
Inc(pos)
|
||||||
|
end;
|
||||||
|
CR, LF: begin
|
||||||
|
pos := HandleCRLF(c, pos);
|
||||||
|
tok.literal := tok.literal +{&} nl;
|
||||||
|
end;
|
||||||
|
lexbase.EndOfFile: begin
|
||||||
|
tok.kind := tkInvalid;
|
||||||
|
break
|
||||||
|
end
|
||||||
|
else begin
|
||||||
|
addChar(tok.literal, buf[pos]);
|
||||||
|
Inc(pos)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
until false;
|
||||||
|
c.bufpos := pos + 3 // skip the three """
|
||||||
|
end
|
||||||
|
else begin // ordinary string literal
|
||||||
|
repeat
|
||||||
|
ch := buf[pos];
|
||||||
|
if ch = '"' then begin
|
||||||
|
inc(pos); // skip '"'
|
||||||
|
break
|
||||||
|
end;
|
||||||
|
if ch in [CR, LF, lexbase.EndOfFile] then begin
|
||||||
|
tok.kind := tkInvalid;
|
||||||
|
break
|
||||||
|
end;
|
||||||
|
if (ch = '\') and not rawMode then begin
|
||||||
|
c.bufPos := pos;
|
||||||
|
getEscapedChar(c, tok);
|
||||||
|
pos := c.bufPos;
|
||||||
|
end
|
||||||
|
else begin
|
||||||
|
addChar(tok.literal, ch);
|
||||||
|
Inc(pos)
|
||||||
|
end
|
||||||
|
until false;
|
||||||
|
c.bufpos := pos;
|
||||||
|
end
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure getSymbol(var c: TCfgParser; var tok: TToken);
|
||||||
|
var
|
||||||
|
pos: int;
|
||||||
|
buf: pchar;
|
||||||
|
begin
|
||||||
|
pos := c.bufpos;
|
||||||
|
buf := c.buf;
|
||||||
|
while true do begin
|
||||||
|
addChar(tok.literal, buf[pos]);
|
||||||
|
Inc(pos);
|
||||||
|
if not (buf[pos] in SymChars) then break;
|
||||||
|
end;
|
||||||
|
c.bufpos := pos;
|
||||||
|
tok.kind := tkSymbol
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure skip(var c: TCfgParser);
|
||||||
|
var
|
||||||
|
buf: PChar;
|
||||||
|
pos: int;
|
||||||
|
begin
|
||||||
|
pos := c.bufpos;
|
||||||
|
buf := c.buf;
|
||||||
|
repeat
|
||||||
|
case buf[pos] of
|
||||||
|
' ': Inc(pos);
|
||||||
|
Tabulator: inc(pos);
|
||||||
|
'#', ';': while not (buf[pos] in [CR, LF, lexbase.EndOfFile]) do inc(pos);
|
||||||
|
CR, LF: pos := HandleCRLF(c, pos);
|
||||||
|
else break // EndOfFile also leaves the loop
|
||||||
|
end
|
||||||
|
until false;
|
||||||
|
c.bufpos := pos;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure rawGetTok(var c: TCfgParser; var tok: TToken);
|
||||||
|
begin
|
||||||
|
tok.kind := tkInvalid;
|
||||||
|
setLength(tok.literal, 0);
|
||||||
|
skip(c);
|
||||||
|
case c.buf[c.bufpos] of
|
||||||
|
'=': begin
|
||||||
|
tok.kind := tkEquals;
|
||||||
|
inc(c.bufpos);
|
||||||
|
tok.literal := '='+'';
|
||||||
|
end;
|
||||||
|
'-': begin
|
||||||
|
inc(c.bufPos);
|
||||||
|
if c.buf[c.bufPos] = '-' then inc(c.bufPos);
|
||||||
|
tok.kind := tkDashDash;
|
||||||
|
tok.literal := '--';
|
||||||
|
end;
|
||||||
|
':': begin
|
||||||
|
tok.kind := tkColon;
|
||||||
|
inc(c.bufpos);
|
||||||
|
tok.literal := ':'+'';
|
||||||
|
end;
|
||||||
|
'r', 'R': begin
|
||||||
|
if c.buf[c.bufPos+1] = '"' then begin
|
||||||
|
Inc(c.bufPos);
|
||||||
|
getString(c, tok, true);
|
||||||
|
end
|
||||||
|
else
|
||||||
|
getSymbol(c, tok);
|
||||||
|
end;
|
||||||
|
'[': begin
|
||||||
|
tok.kind := tkBracketLe;
|
||||||
|
inc(c.bufpos);
|
||||||
|
tok.literal := '['+'';
|
||||||
|
end;
|
||||||
|
']': begin
|
||||||
|
tok.kind := tkBracketRi;
|
||||||
|
Inc(c.bufpos);
|
||||||
|
tok.literal := ']'+'';
|
||||||
|
end;
|
||||||
|
'"': getString(c, tok, false);
|
||||||
|
lexbase.EndOfFile: tok.kind := tkEof;
|
||||||
|
else getSymbol(c, tok);
|
||||||
|
end
|
||||||
|
end;
|
||||||
|
|
||||||
|
function errorStr(const c: TCfgParser; const msg: string): string;
|
||||||
|
begin
|
||||||
|
result := format('$1($2, $3) Error: $4', [
|
||||||
|
c.filename, toString(getLine(c)), toString(getColumn(c)),
|
||||||
|
msg
|
||||||
|
]);
|
||||||
|
end;
|
||||||
|
|
||||||
|
function getKeyValPair(var c: TCfgParser; kind: TCfgEventKind): TCfgEvent;
|
||||||
|
begin
|
||||||
|
if c.tok.kind = tkSymbol then begin
|
||||||
|
result.kind := kind;
|
||||||
|
result.key := c.tok.literal;
|
||||||
|
result.value := '';
|
||||||
|
rawGetTok(c, c.tok);
|
||||||
|
if c.tok.kind in [tkEquals, tkColon] then begin
|
||||||
|
rawGetTok(c, c.tok);
|
||||||
|
if c.tok.kind = tkSymbol then begin
|
||||||
|
result.value := c.tok.literal;
|
||||||
|
end
|
||||||
|
else begin
|
||||||
|
result.kind := cfgError;
|
||||||
|
result.msg := errorStr(c, 'symbol expected, but found: '
|
||||||
|
+ c.tok.literal);
|
||||||
|
end;
|
||||||
|
rawGetTok(c, c.tok);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else begin
|
||||||
|
result.kind := cfgError;
|
||||||
|
result.msg := errorStr(c, 'symbol expected, but found: ' + c.tok.literal);
|
||||||
|
rawGetTok(c, c.tok);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function next(var c: TCfgParser): TCfgEvent;
|
||||||
|
begin
|
||||||
|
case c.tok.kind of
|
||||||
|
tkEof: result.kind := cfgEof;
|
||||||
|
tkDashDash: begin
|
||||||
|
rawGetTok(c, c.tok);
|
||||||
|
result := getKeyValPair(c, cfgOption);
|
||||||
|
end;
|
||||||
|
tkSymbol: begin
|
||||||
|
result := getKeyValPair(c, cfgKeyValuePair);
|
||||||
|
end;
|
||||||
|
tkBracketLe: begin
|
||||||
|
rawGetTok(c, c.tok);
|
||||||
|
if c.tok.kind = tkSymbol then begin
|
||||||
|
result.kind := cfgSectionStart;
|
||||||
|
result.section := c.tok.literal;
|
||||||
|
end
|
||||||
|
else begin
|
||||||
|
result.kind := cfgError;
|
||||||
|
result.msg := errorStr(c, 'symbol expected, but found: ' + c.tok.literal);
|
||||||
|
end;
|
||||||
|
rawGetTok(c, c.tok);
|
||||||
|
if c.tok.kind = tkBracketRi then rawGetTok(c, c.tok)
|
||||||
|
else begin
|
||||||
|
result.kind := cfgError;
|
||||||
|
result.msg := errorStr(c, ''']'' expected, but found: ' + c.tok.literal);
|
||||||
|
end
|
||||||
|
end;
|
||||||
|
tkInvalid, tkEquals, tkColon: begin
|
||||||
|
result.kind := cfgError;
|
||||||
|
result.msg := errorStr(c, 'invalid token: ' + c.tok.literal);
|
||||||
|
rawGetTok(c, c.tok);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end;
|
||||||
|
|
||||||
|
end.
|
||||||
153
nim/parseopt.pas
Normal file
153
nim/parseopt.pas
Normal file
|
|
@ -0,0 +1,153 @@
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Nimrod's Runtime Library
|
||||||
|
// (c) Copyright 2008 Andreas Rumpf
|
||||||
|
//
|
||||||
|
// See the file "copying.txt", included in this
|
||||||
|
// distribution, for details about the copyright.
|
||||||
|
//
|
||||||
|
unit parseopt;
|
||||||
|
|
||||||
|
// A command line parser; the Nimrod version of this file
|
||||||
|
// will become part of the standard library.
|
||||||
|
|
||||||
|
interface
|
||||||
|
|
||||||
|
{$include 'config.inc'}
|
||||||
|
|
||||||
|
uses
|
||||||
|
nsystem, charsets, nos, strutils;
|
||||||
|
|
||||||
|
type
|
||||||
|
TCmdLineKind = (
|
||||||
|
cmdEnd, // end of command line reached
|
||||||
|
cmdArgument, // argument detected
|
||||||
|
cmdLongoption, // a long option ``--option`` detected
|
||||||
|
cmdShortOption // a short option ``-c`` detected
|
||||||
|
);
|
||||||
|
TOptParser = object(NObject)
|
||||||
|
cmd: string;
|
||||||
|
pos: int;
|
||||||
|
inShortState: bool;
|
||||||
|
kind: TCmdLineKind;
|
||||||
|
key, val: string;
|
||||||
|
end;
|
||||||
|
|
||||||
|
function init(const cmdline: string = ''): TOptParser;
|
||||||
|
procedure next(var p: TOptParser);
|
||||||
|
|
||||||
|
function getRestOfCommandLine(const p: TOptParser): string;
|
||||||
|
|
||||||
|
implementation
|
||||||
|
|
||||||
|
function init(const cmdline: string = ''): TOptParser;
|
||||||
|
var
|
||||||
|
i: int;
|
||||||
|
begin
|
||||||
|
result.pos := strStart;
|
||||||
|
result.inShortState := false;
|
||||||
|
if cmdline <> '' then
|
||||||
|
result.cmd := cmdline
|
||||||
|
else begin
|
||||||
|
result.cmd := '';
|
||||||
|
for i := 1 to ParamCount() do
|
||||||
|
result.cmd := result.cmd +{&} quoteIfSpaceExists(paramStr(i)) +{&} ' ';
|
||||||
|
{@ignore}
|
||||||
|
result.cmd := result.cmd + #0;
|
||||||
|
{@emit}
|
||||||
|
end;
|
||||||
|
result.kind := cmdEnd;
|
||||||
|
result.key := '';
|
||||||
|
result.val := '';
|
||||||
|
end;
|
||||||
|
|
||||||
|
function parseWord(const s: string; const i: int; var w: string;
|
||||||
|
const delim: TCharSet = {@set}[#9, ' ', #0]): int;
|
||||||
|
begin
|
||||||
|
result := i;
|
||||||
|
if s[result] = '"' then begin
|
||||||
|
inc(result);
|
||||||
|
while not (s[result] in [#0, '"']) do begin
|
||||||
|
addChar(w, s[result]);
|
||||||
|
inc(result);
|
||||||
|
end;
|
||||||
|
if s[result] = '"' then inc(result)
|
||||||
|
end
|
||||||
|
else begin
|
||||||
|
while not (s[result] in delim) do begin
|
||||||
|
addChar(w, s[result]);
|
||||||
|
inc(result);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure handleShortOption(var p: TOptParser);
|
||||||
|
var
|
||||||
|
i: int;
|
||||||
|
begin
|
||||||
|
i := p.pos;
|
||||||
|
p.kind := cmdShortOption;
|
||||||
|
addChar(p.key, p.cmd[i]);
|
||||||
|
inc(i);
|
||||||
|
p.inShortState := true;
|
||||||
|
while p.cmd[i] in [#9, ' '] do begin
|
||||||
|
inc(i);
|
||||||
|
p.inShortState := false;
|
||||||
|
end;
|
||||||
|
if p.cmd[i] in [':', '='] then begin
|
||||||
|
inc(i); p.inShortState := false;
|
||||||
|
while p.cmd[i] in [#9, ' '] do inc(i);
|
||||||
|
i := parseWord(p.cmd, i, p.val);
|
||||||
|
end;
|
||||||
|
if p.cmd[i] = #0 then p.inShortState := false;
|
||||||
|
p.pos := i;
|
||||||
|
end;
|
||||||
|
|
||||||
|
procedure next(var p: TOptParser);
|
||||||
|
var
|
||||||
|
i: int;
|
||||||
|
begin
|
||||||
|
i := p.pos;
|
||||||
|
while p.cmd[i] in [#9, ' '] do inc(i);
|
||||||
|
p.pos := i;
|
||||||
|
setLength(p.key, 0);
|
||||||
|
setLength(p.val, 0);
|
||||||
|
if p.inShortState then begin
|
||||||
|
handleShortOption(p); exit
|
||||||
|
end;
|
||||||
|
case p.cmd[i] of
|
||||||
|
#0: p.kind := cmdEnd;
|
||||||
|
'-': begin
|
||||||
|
inc(i);
|
||||||
|
if p.cmd[i] = '-' then begin
|
||||||
|
p.kind := cmdLongOption;
|
||||||
|
inc(i);
|
||||||
|
i := parseWord(p.cmd, i, p.key, {@set}[#0, ' ', #9, ':', '=']);
|
||||||
|
while p.cmd[i] in [#9, ' '] do inc(i);
|
||||||
|
if p.cmd[i] in [':', '='] then begin
|
||||||
|
inc(i);
|
||||||
|
while p.cmd[i] in [#9, ' '] do inc(i);
|
||||||
|
p.pos := parseWord(p.cmd, i, p.val);
|
||||||
|
end
|
||||||
|
else
|
||||||
|
p.pos := i;
|
||||||
|
end
|
||||||
|
else begin
|
||||||
|
p.pos := i;
|
||||||
|
handleShortOption(p)
|
||||||
|
end
|
||||||
|
end;
|
||||||
|
else begin
|
||||||
|
p.kind := cmdArgument;
|
||||||
|
p.pos := parseWord(p.cmd, i, p.key);
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end;
|
||||||
|
|
||||||
|
function getRestOfCommandLine(const p: TOptParser): string;
|
||||||
|
begin
|
||||||
|
result := strip(ncopy(p.cmd, p.pos+strStart, length(p.cmd)-1))
|
||||||
|
// always -1, because Pascal version uses a trailing zero here
|
||||||
|
end;
|
||||||
|
|
||||||
|
end.
|
||||||
|
|
@ -70,6 +70,7 @@ type
|
||||||
pxSymbol, // a symbol
|
pxSymbol, // a symbol
|
||||||
|
|
||||||
pxIntLit,
|
pxIntLit,
|
||||||
|
pxInt64Lit, // long constant like 0x00000070fffffff or out of int range
|
||||||
pxFloatLit,
|
pxFloatLit,
|
||||||
|
|
||||||
pxParLe, pxParRi, pxBracketLe, pxBracketRi,
|
pxParLe, pxParRi, pxBracketLe, pxBracketRi,
|
||||||
|
|
@ -110,7 +111,8 @@ const
|
||||||
'with', 'xor',
|
'with', 'xor',
|
||||||
//[[[end]]]
|
//[[[end]]]
|
||||||
'pxComment', 'pxCommand',
|
'pxComment', 'pxCommand',
|
||||||
'{&}', '{%}', 'pxStrLit', '[IDENTIFIER]', 'pxIntLit', 'pxFloatLit',
|
'{&}', '{%}', 'pxStrLit', '[IDENTIFIER]', 'pxIntLit', 'pxInt64Lit',
|
||||||
|
'pxFloatLit',
|
||||||
'('+'', ')'+'', '['+'', ']'+'',
|
'('+'', ')'+'', '['+'', ']'+'',
|
||||||
','+'', ';'+'', ':'+'',
|
','+'', ';'+'', ':'+'',
|
||||||
':=', '='+'', '.'+'', '..', '^'+'', '+'+'', '-'+'', '*'+'', '/'+'',
|
':=', '='+'', '.'+'', '..', '^'+'', '+'+'', '-'+'', '*'+'', '/'+'',
|
||||||
|
|
@ -135,7 +137,7 @@ implementation
|
||||||
function pastokToStr(const tok: TPasTok): string;
|
function pastokToStr(const tok: TPasTok): string;
|
||||||
begin
|
begin
|
||||||
case tok.xkind of
|
case tok.xkind of
|
||||||
pxIntLit:
|
pxIntLit, pxInt64Lit:
|
||||||
result := toString(tok.iNumber);
|
result := toString(tok.iNumber);
|
||||||
pxFloatLit:
|
pxFloatLit:
|
||||||
result := toStringF(tok.fNumber);
|
result := toStringF(tok.fNumber);
|
||||||
|
|
@ -271,7 +273,7 @@ end;
|
||||||
|
|
||||||
procedure getNumber2(var L: TPasLex; var tok: TPasTok);
|
procedure getNumber2(var L: TPasLex; var tok: TPasTok);
|
||||||
var
|
var
|
||||||
pos: int;
|
pos, bits: int;
|
||||||
xi: biggestInt;
|
xi: biggestInt;
|
||||||
begin
|
begin
|
||||||
pos := L.bufpos+1; // skip %
|
pos := L.bufpos+1; // skip %
|
||||||
|
|
@ -284,6 +286,7 @@ begin
|
||||||
|
|
||||||
tok.base := base2;
|
tok.base := base2;
|
||||||
xi := 0;
|
xi := 0;
|
||||||
|
bits := 0;
|
||||||
while true do begin
|
while true do begin
|
||||||
case L.buf[pos] of
|
case L.buf[pos] of
|
||||||
'A'..'Z', 'a'..'z', '2'..'9', '.': begin
|
'A'..'Z', 'a'..'z', '2'..'9', '.': begin
|
||||||
|
|
@ -294,23 +297,28 @@ begin
|
||||||
'0', '1': begin
|
'0', '1': begin
|
||||||
xi := (xi shl 1) or (ord(L.buf[pos]) - ord('0'));
|
xi := (xi shl 1) or (ord(L.buf[pos]) - ord('0'));
|
||||||
inc(pos);
|
inc(pos);
|
||||||
|
inc(bits);
|
||||||
end;
|
end;
|
||||||
else break;
|
else break;
|
||||||
end
|
end
|
||||||
end;
|
end;
|
||||||
tok.iNumber := xi;
|
tok.iNumber := xi;
|
||||||
|
if (bits > 32) then //or (xi < low(int32)) or (xi > high(int32)) then
|
||||||
|
tok.xkind := pxInt64Lit
|
||||||
|
else
|
||||||
tok.xkind := pxIntLit;
|
tok.xkind := pxIntLit;
|
||||||
L.bufpos := pos;
|
L.bufpos := pos;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure getNumber16(var L: TPasLex; var tok: TPasTok);
|
procedure getNumber16(var L: TPasLex; var tok: TPasTok);
|
||||||
var
|
var
|
||||||
pos: int;
|
pos, bits: int;
|
||||||
xi: biggestInt;
|
xi: biggestInt;
|
||||||
begin
|
begin
|
||||||
pos := L.bufpos+1; // skip $
|
pos := L.bufpos+1; // skip $
|
||||||
tok.base := base16;
|
tok.base := base16;
|
||||||
xi := 0;
|
xi := 0;
|
||||||
|
bits := 0;
|
||||||
while true do begin
|
while true do begin
|
||||||
case L.buf[pos] of
|
case L.buf[pos] of
|
||||||
'G'..'Z', 'g'..'z', '.': begin
|
'G'..'Z', 'g'..'z', '.': begin
|
||||||
|
|
@ -321,19 +329,25 @@ begin
|
||||||
'0'..'9': begin
|
'0'..'9': begin
|
||||||
xi := (xi shl 4) or (ord(L.buf[pos]) - ord('0'));
|
xi := (xi shl 4) or (ord(L.buf[pos]) - ord('0'));
|
||||||
inc(pos);
|
inc(pos);
|
||||||
|
inc(bits, 4);
|
||||||
end;
|
end;
|
||||||
'a'..'f': begin
|
'a'..'f': begin
|
||||||
xi := (xi shl 4) or (ord(L.buf[pos]) - ord('a') + 10);
|
xi := (xi shl 4) or (ord(L.buf[pos]) - ord('a') + 10);
|
||||||
inc(pos);
|
inc(pos);
|
||||||
|
inc(bits, 4);
|
||||||
end;
|
end;
|
||||||
'A'..'F': begin
|
'A'..'F': begin
|
||||||
xi := (xi shl 4) or (ord(L.buf[pos]) - ord('A') + 10);
|
xi := (xi shl 4) or (ord(L.buf[pos]) - ord('A') + 10);
|
||||||
inc(pos);
|
inc(pos);
|
||||||
|
inc(bits, 4);
|
||||||
end;
|
end;
|
||||||
else break;
|
else break;
|
||||||
end
|
end
|
||||||
end;
|
end;
|
||||||
tok.iNumber := xi;
|
tok.iNumber := xi;
|
||||||
|
if (bits > 32) then // (xi < low(int32)) or (xi > high(int32)) then
|
||||||
|
tok.xkind := pxInt64Lit
|
||||||
|
else
|
||||||
tok.xkind := pxIntLit;
|
tok.xkind := pxIntLit;
|
||||||
L.bufpos := pos;
|
L.bufpos := pos;
|
||||||
end;
|
end;
|
||||||
|
|
@ -354,6 +368,9 @@ begin
|
||||||
end
|
end
|
||||||
else begin
|
else begin
|
||||||
tok.iNumber := ParseInt(tok.literal);
|
tok.iNumber := ParseInt(tok.literal);
|
||||||
|
if (tok.iNumber < low(int32)) or (tok.iNumber > high(int32)) then
|
||||||
|
tok.xkind := pxInt64Lit
|
||||||
|
else
|
||||||
tok.xkind := pxIntLit;
|
tok.xkind := pxIntLit;
|
||||||
end;
|
end;
|
||||||
except
|
except
|
||||||
|
|
|
||||||
100
nim/pasparse.pas
100
nim/pasparse.pas
|
|
@ -322,6 +322,10 @@ begin
|
||||||
result := newNodeP(nkPtrTy, p);
|
result := newNodeP(nkPtrTy, p);
|
||||||
getTok(p); eat(p, pxCurlyDirRi);
|
getTok(p); eat(p, pxCurlyDirRi);
|
||||||
end
|
end
|
||||||
|
else if p.tok.ident.id = getIdent('tuple').id then begin
|
||||||
|
result := newNodeP(nkTupleTy, p);
|
||||||
|
getTok(p); eat(p, pxCurlyDirRi);
|
||||||
|
end
|
||||||
else begin
|
else begin
|
||||||
parMessage(p, errUnknownDirective, pasTokToStr(p.tok));
|
parMessage(p, errUnknownDirective, pasTokToStr(p.tok));
|
||||||
while true do begin
|
while true do begin
|
||||||
|
|
@ -481,6 +485,16 @@ begin
|
||||||
exprListAux(p, elemKind, endTok, sepTok, result);
|
exprListAux(p, elemKind, endTok, sepTok, result);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure setBaseFlags(n: PNode; base: TNumericalBase);
|
||||||
|
begin
|
||||||
|
case base of
|
||||||
|
base10: begin end;
|
||||||
|
base2: include(n.flags, nfBase2);
|
||||||
|
base8: include(n.flags, nfBase8);
|
||||||
|
base16: include(n.flags, nfBase16);
|
||||||
|
end
|
||||||
|
end;
|
||||||
|
|
||||||
function identOrLiteral(var p: TPasParser): PNode;
|
function identOrLiteral(var p: TPasParser): PNode;
|
||||||
var
|
var
|
||||||
a: PNode;
|
a: PNode;
|
||||||
|
|
@ -493,12 +507,17 @@ begin
|
||||||
// literals
|
// literals
|
||||||
pxIntLit: begin
|
pxIntLit: begin
|
||||||
result := newIntNodeP(nkIntLit, p.tok.iNumber, p);
|
result := newIntNodeP(nkIntLit, p.tok.iNumber, p);
|
||||||
result.base := p.tok.base;
|
setBaseFlags(result, p.tok.base);
|
||||||
|
getTok(p);
|
||||||
|
end;
|
||||||
|
pxInt64Lit: begin
|
||||||
|
result := newIntNodeP(nkInt64Lit, p.tok.iNumber, p);
|
||||||
|
setBaseFlags(result, p.tok.base);
|
||||||
getTok(p);
|
getTok(p);
|
||||||
end;
|
end;
|
||||||
pxFloatLit: begin
|
pxFloatLit: begin
|
||||||
result := newFloatNodeP(nkFloatLit, p.tok.fNumber, p);
|
result := newFloatNodeP(nkFloatLit, p.tok.fNumber, p);
|
||||||
result.base := p.tok.base;
|
setBaseFlags(result, p.tok.base);
|
||||||
getTok(p);
|
getTok(p);
|
||||||
end;
|
end;
|
||||||
pxStrLit: begin
|
pxStrLit: begin
|
||||||
|
|
@ -683,6 +702,7 @@ begin
|
||||||
end
|
end
|
||||||
else begin end
|
else begin end
|
||||||
end;
|
end;
|
||||||
|
if not (n.kind in [nkEmpty..nkNilLit]) then
|
||||||
for i := 0 to sonsLen(n)-1 do
|
for i := 0 to sonsLen(n)-1 do
|
||||||
result.sons[i] := fixExpr(n.sons[i])
|
result.sons[i] := fixExpr(n.sons[i])
|
||||||
end;
|
end;
|
||||||
|
|
@ -948,6 +968,7 @@ begin
|
||||||
if p.tok.xkind <> pxIf then begin
|
if p.tok.xkind <> pxIf then begin
|
||||||
// ordinary else part:
|
// ordinary else part:
|
||||||
branch := newNodeP(nkElse, p);
|
branch := newNodeP(nkElse, p);
|
||||||
|
skipCom(p, result); // BUGFIX
|
||||||
addSon(branch, parseStmt(p));
|
addSon(branch, parseStmt(p));
|
||||||
addSon(result, branch);
|
addSon(result, branch);
|
||||||
break
|
break
|
||||||
|
|
@ -1235,6 +1256,14 @@ begin
|
||||||
noBody := true;
|
noBody := true;
|
||||||
getTok(p); opt(p, pxSemicolon);
|
getTok(p); opt(p, pxSemicolon);
|
||||||
end;
|
end;
|
||||||
|
wNoConv: begin
|
||||||
|
// This is a fake for platform module. There is no ``noconv``
|
||||||
|
// directive in Pascal.
|
||||||
|
if result = nil then result := newNodeP(nkPragma, p);
|
||||||
|
addSon(result, newIdentNodeP(getIdent('noconv'), p));
|
||||||
|
noBody := true;
|
||||||
|
getTok(p); opt(p, pxSemicolon);
|
||||||
|
end;
|
||||||
wVarargs: begin
|
wVarargs: begin
|
||||||
if result = nil then result := newNodeP(nkPragma, p);
|
if result = nil then result := newNodeP(nkPragma, p);
|
||||||
addSon(result, newIdentNodeP(getIdent('varargs'), p));
|
addSon(result, newIdentNodeP(getIdent('varargs'), p));
|
||||||
|
|
@ -1464,7 +1493,7 @@ begin
|
||||||
nkIdent, nkAccQuoted: begin
|
nkIdent, nkAccQuoted: begin
|
||||||
a := newNode(nkPostFix);
|
a := newNode(nkPostFix);
|
||||||
a.info := n.info;
|
a.info := n.info;
|
||||||
addSon(a, newIdentNode(getIdent('*'+'')));
|
addSon(a, newIdentNode(getIdent('*'+''), n.info));
|
||||||
addSon(a, n);
|
addSon(a, n);
|
||||||
n := a
|
n := a
|
||||||
end;
|
end;
|
||||||
|
|
@ -1486,7 +1515,7 @@ begin
|
||||||
end
|
end
|
||||||
end;
|
end;
|
||||||
nkRecList, nkRecWhen, nkElse, nkOfBranch, nkElifBranch,
|
nkRecList, nkRecWhen, nkElse, nkOfBranch, nkElifBranch,
|
||||||
nkRecordTy, nkObjectTy: begin
|
nkObjectTy: begin
|
||||||
for i := 0 to sonsLen(n)-1 do fixRecordDef(n.sons[i])
|
for i := 0 to sonsLen(n)-1 do fixRecordDef(n.sons[i])
|
||||||
end;
|
end;
|
||||||
nkIdentDefs: begin
|
nkIdentDefs: begin
|
||||||
|
|
@ -1497,6 +1526,19 @@ begin
|
||||||
end
|
end
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure parseRecordBody(var p: TPasParser; result: PNode);
|
||||||
|
var
|
||||||
|
a: PNode;
|
||||||
|
begin
|
||||||
|
skipCom(p, result);
|
||||||
|
a := parseRecordPart(p);
|
||||||
|
if result.kind <> nkTupleTy then fixRecordDef(a);
|
||||||
|
addSon(result, a);
|
||||||
|
eat(p, pxEnd);
|
||||||
|
opt(p, pxSemicolon);
|
||||||
|
skipCom(p, result);
|
||||||
|
end;
|
||||||
|
|
||||||
function parseRecordOrObject(var p: TPasParser; kind: TNodeKind): PNode;
|
function parseRecordOrObject(var p: TPasParser; kind: TNodeKind): PNode;
|
||||||
var
|
var
|
||||||
a: PNode;
|
a: PNode;
|
||||||
|
|
@ -1512,19 +1554,14 @@ begin
|
||||||
eat(p, pxParRi);
|
eat(p, pxParRi);
|
||||||
end
|
end
|
||||||
else addSon(result, nil);
|
else addSon(result, nil);
|
||||||
skipCom(p, result);
|
parseRecordBody(p, result);
|
||||||
a := parseRecordPart(p);
|
|
||||||
fixRecordDef(a);
|
|
||||||
addSon(result, a);
|
|
||||||
eat(p, pxEnd);
|
|
||||||
opt(p, pxSemicolon);
|
|
||||||
skipCom(p, result);
|
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function parseTypeDesc(var p: TPasParser): PNode;
|
function parseTypeDesc(var p: TPasParser): PNode;
|
||||||
var
|
var
|
||||||
oldcontext: TPasContext;
|
oldcontext: TPasContext;
|
||||||
a, r: PNode;
|
a, r: PNode;
|
||||||
|
i: int;
|
||||||
begin
|
begin
|
||||||
oldcontext := p.context;
|
oldcontext := p.context;
|
||||||
p.context := conTypeDesc;
|
p.context := conTypeDesc;
|
||||||
|
|
@ -1532,7 +1569,28 @@ begin
|
||||||
case p.tok.xkind of
|
case p.tok.xkind of
|
||||||
pxCommand: result := parseCommand(p);
|
pxCommand: result := parseCommand(p);
|
||||||
pxProcedure, pxFunction: result := parseRoutineType(p);
|
pxProcedure, pxFunction: result := parseRoutineType(p);
|
||||||
pxRecord: result := parseRecordOrObject(p, nkRecordTy);
|
pxRecord: begin
|
||||||
|
getTok(p);
|
||||||
|
if p.tok.xkind = pxCommand then begin
|
||||||
|
result := parseCommand(p);
|
||||||
|
if result.kind <> nkTupleTy then
|
||||||
|
InternalError(result.info, 'parseTypeDesc');
|
||||||
|
parseRecordBody(p, result);
|
||||||
|
a := lastSon(result);
|
||||||
|
// embed nkRecList directly into nkTupleTy
|
||||||
|
for i := 0 to sonsLen(a)-1 do
|
||||||
|
if i = 0 then result.sons[sonsLen(result)-1] := a.sons[0]
|
||||||
|
else addSon(result, a.sons[i]);
|
||||||
|
end
|
||||||
|
else begin
|
||||||
|
result := newNodeP(nkReturnToken, p);
|
||||||
|
// we use nkReturnToken to signal that this object should be marked as
|
||||||
|
// final
|
||||||
|
addSon(result, nil);
|
||||||
|
addSon(result, nil);
|
||||||
|
parseRecordBody(p, result);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
pxObject: result := parseRecordOrObject(p, nkObjectTy);
|
pxObject: result := parseRecordOrObject(p, nkObjectTy);
|
||||||
pxParLe: result := parseEnum(p);
|
pxParLe: result := parseEnum(p);
|
||||||
pxArray: begin
|
pxArray: begin
|
||||||
|
|
@ -1591,13 +1649,29 @@ begin
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function parseTypeDef(var p: TPasParser): PNode;
|
function parseTypeDef(var p: TPasParser): PNode;
|
||||||
|
var
|
||||||
|
a, e, pragmasNode: PNode;
|
||||||
begin
|
begin
|
||||||
result := newNodeP(nkTypeDef, p);
|
result := newNodeP(nkTypeDef, p);
|
||||||
addSon(result, identVis(p));
|
addSon(result, identVis(p));
|
||||||
addSon(result, nil); // generic params
|
addSon(result, nil); // generic params
|
||||||
if p.tok.xkind = pxEquals then begin
|
if p.tok.xkind = pxEquals then begin
|
||||||
getTok(p); skipCom(p, result);
|
getTok(p); skipCom(p, result);
|
||||||
addSon(result, parseTypeDesc(p));
|
a := parseTypeDesc(p);
|
||||||
|
addSon(result, a);
|
||||||
|
if a.kind = nkReturnToken then begin // a `final` object?
|
||||||
|
a.kind := nkObjectTy;
|
||||||
|
if result.sons[0].kind <> nkPragmaExpr then begin
|
||||||
|
e := newNodeP(nkPragmaExpr, p);
|
||||||
|
pragmasNode := newNodeP(nkPragma, p);
|
||||||
|
addSon(e, result.sons[0]);
|
||||||
|
addSon(e, pragmasNode);
|
||||||
|
result.sons[0] := e;
|
||||||
|
end
|
||||||
|
else
|
||||||
|
pragmasNode := result.sons[1];
|
||||||
|
addSon(pragmasNode, newIdentNodeP(getIdent('final'), p));
|
||||||
|
end
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
addSon(result, nil);
|
addSon(result, nil);
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ unit platform;
|
||||||
// Note: Unfortunately if an OS or CPU is listed here this does not mean that
|
// Note: Unfortunately if an OS or CPU is listed here this does not mean that
|
||||||
// Nimrod has been tested on this platform or that the RTL has been ported.
|
// Nimrod has been tested on this platform or that the RTL has been ported.
|
||||||
// Feel free to test for your exentric platform! (Windows on I386 and Linux
|
// Feel free to test for your exentric platform! (Windows on I386 and Linux
|
||||||
// on AMD64 have been tested, though.)
|
// on I386 have been tested, though.)
|
||||||
|
|
||||||
interface
|
interface
|
||||||
|
|
||||||
|
|
@ -45,7 +45,8 @@ type
|
||||||
osAtari,
|
osAtari,
|
||||||
osNetware,
|
osNetware,
|
||||||
osMacos,
|
osMacos,
|
||||||
osMacosx
|
osMacosx,
|
||||||
|
osEcmaScript
|
||||||
);
|
);
|
||||||
type
|
type
|
||||||
TInfoOSProp = (
|
TInfoOSProp = (
|
||||||
|
|
@ -55,7 +56,7 @@ type
|
||||||
);
|
);
|
||||||
|
|
||||||
TInfoOSProps = set of TInfoOSProp;
|
TInfoOSProps = set of TInfoOSProp;
|
||||||
TInfoOS = record
|
TInfoOS = record{@tuple}
|
||||||
name: string;
|
name: string;
|
||||||
parDir: string;
|
parDir: string;
|
||||||
dllExt: string;
|
dllExt: string;
|
||||||
|
|
@ -360,6 +361,22 @@ const
|
||||||
exeExt: '';
|
exeExt: '';
|
||||||
extSep: '.'+'';
|
extSep: '.'+'';
|
||||||
props: {@set}[ospNeedsPIC, ospPosix];
|
props: {@set}[ospNeedsPIC, ospPosix];
|
||||||
|
),
|
||||||
|
(
|
||||||
|
name: 'EcmaScript';
|
||||||
|
parDir: '..';
|
||||||
|
dllExt: '.so';
|
||||||
|
altDirSep: '/'+'';
|
||||||
|
dllPrefix: 'lib';
|
||||||
|
objExt: '.o';
|
||||||
|
newLine: #10+'';
|
||||||
|
pathSep: ':'+'';
|
||||||
|
dirSep: '/'+'';
|
||||||
|
scriptExt: '.sh';
|
||||||
|
curDir: '.'+'';
|
||||||
|
exeExt: '';
|
||||||
|
extSep: '.'+'';
|
||||||
|
props: {@set}[];
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
type
|
type
|
||||||
|
|
@ -377,11 +394,12 @@ type
|
||||||
cpuIa64,
|
cpuIa64,
|
||||||
cpuAmd64,
|
cpuAmd64,
|
||||||
cpuMips,
|
cpuMips,
|
||||||
cpuArm
|
cpuArm,
|
||||||
|
cpuEcmaScript
|
||||||
);
|
);
|
||||||
type
|
type
|
||||||
TEndian = (littleEndian, bigEndian);
|
TEndian = (littleEndian, bigEndian);
|
||||||
TInfoCPU = record
|
TInfoCPU = record{@tuple}
|
||||||
name: string;
|
name: string;
|
||||||
intSize: int;
|
intSize: int;
|
||||||
endian: TEndian;
|
endian: TEndian;
|
||||||
|
|
@ -460,6 +478,13 @@ const
|
||||||
endian: littleEndian;
|
endian: littleEndian;
|
||||||
floatSize: 64;
|
floatSize: 64;
|
||||||
bit: 32;
|
bit: 32;
|
||||||
|
),
|
||||||
|
(
|
||||||
|
name: 'ecmascript';
|
||||||
|
intSize: 32;
|
||||||
|
endian: bigEndian;
|
||||||
|
floatSize: 64;
|
||||||
|
bit: 32;
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
@ -517,9 +542,9 @@ end;
|
||||||
// this is Ok for the Pascal version, but the Nimrod version needs a different
|
// this is Ok for the Pascal version, but the Nimrod version needs a different
|
||||||
// mechanism
|
// mechanism
|
||||||
{@emit
|
{@emit
|
||||||
procedure nimCPU(): cstring; importc;}
|
procedure nimCPU(): cstring; importc; noconv;}
|
||||||
{@emit
|
{@emit
|
||||||
procedure nimOS(): cstring; importc;}
|
procedure nimOS(): cstring; importc; noconv;}
|
||||||
|
|
||||||
{@ignore}
|
{@ignore}
|
||||||
initialization
|
initialization
|
||||||
|
|
|
||||||
|
|
@ -240,6 +240,9 @@ begin
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function parseSymbol(var p: TParser): PNode;
|
function parseSymbol(var p: TParser): PNode;
|
||||||
|
var
|
||||||
|
s: string;
|
||||||
|
id: PIdent;
|
||||||
begin
|
begin
|
||||||
case p.tok.tokType of
|
case p.tok.tokType of
|
||||||
tkSymbol: begin
|
tkSymbol: begin
|
||||||
|
|
@ -251,9 +254,31 @@ begin
|
||||||
getTok(p);
|
getTok(p);
|
||||||
case p.tok.tokType of
|
case p.tok.tokType of
|
||||||
tkBracketLe: begin
|
tkBracketLe: begin
|
||||||
addSon(result, newIdentNodeP(getIdent('[]'), p));
|
s := '['+'';
|
||||||
getTok(p);
|
getTok(p);
|
||||||
|
if (p.tok.tokType = tkOpr) and (p.tok.ident.s = '$'+'') then begin
|
||||||
|
s := s + '$..';
|
||||||
|
getTok(p);
|
||||||
|
eat(p, tkDotDot);
|
||||||
|
if (p.tok.tokType = tkOpr) and (p.tok.ident.s = '$'+'') then begin
|
||||||
|
s := s + '$'+'';
|
||||||
|
getTok(p);
|
||||||
|
end;
|
||||||
|
end
|
||||||
|
else if p.tok.tokType = tkDotDot then begin
|
||||||
|
s := s + '..';
|
||||||
|
getTok(p);
|
||||||
|
if (p.tok.tokType = tkOpr) and (p.tok.ident.s = '$'+'') then begin
|
||||||
|
s := s + '$'+'';
|
||||||
|
getTok(p);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
eat(p, tkBracketRi);
|
eat(p, tkBracketRi);
|
||||||
|
s := s + ']'+'';
|
||||||
|
if p.tok.tokType = tkEquals then begin
|
||||||
|
s := s + '='; getTok(p);
|
||||||
|
end;
|
||||||
|
addSon(result, newIdentNodeP(getIdent(s), p));
|
||||||
end;
|
end;
|
||||||
tkParLe: begin
|
tkParLe: begin
|
||||||
addSon(result, newIdentNodeP(getIdent('()'), p));
|
addSon(result, newIdentNodeP(getIdent('()'), p));
|
||||||
|
|
@ -261,8 +286,14 @@ begin
|
||||||
eat(p, tkParRi);
|
eat(p, tkParRi);
|
||||||
end;
|
end;
|
||||||
tokKeywordLow..tokKeywordHigh, tkSymbol, tkOpr: begin
|
tokKeywordLow..tokKeywordHigh, tkSymbol, tkOpr: begin
|
||||||
addSon(result, newIdentNodeP(p.tok.ident, p));
|
id := p.tok.ident;
|
||||||
getTok(p);
|
getTok(p);
|
||||||
|
if p.tok.tokType = tkEquals then begin
|
||||||
|
addSon(result, newIdentNodeP(getIdent(id.s + '='), p));
|
||||||
|
getTok(p);
|
||||||
|
end
|
||||||
|
else
|
||||||
|
addSon(result, newIdentNodeP(id, p));
|
||||||
end;
|
end;
|
||||||
else begin
|
else begin
|
||||||
parMessage(p, errIdentifierExpected, tokToStr(p.tok));
|
parMessage(p, errIdentifierExpected, tokToStr(p.tok));
|
||||||
|
|
@ -350,7 +381,7 @@ var
|
||||||
begin
|
begin
|
||||||
case p.tok.tokType of
|
case p.tok.tokType of
|
||||||
tkDotDot: result := dotdotExpr(p);
|
tkDotDot: result := dotdotExpr(p);
|
||||||
tkVar, tkRef, tkPtr, tkProc, tkType: result := parseTypeDescK(p);
|
tkVar, tkRef, tkPtr, tkProc, tkTuple, tkType: result := parseTypeDescK(p);
|
||||||
else begin
|
else begin
|
||||||
a := parseExpr(p);
|
a := parseExpr(p);
|
||||||
case p.tok.tokType of
|
case p.tok.tokType of
|
||||||
|
|
@ -519,6 +550,16 @@ begin
|
||||||
eat(p, tkParRi);
|
eat(p, tkParRi);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure setBaseFlags(n: PNode; base: TNumericalBase);
|
||||||
|
begin
|
||||||
|
case base of
|
||||||
|
base10: begin end;
|
||||||
|
base2: include(n.flags, nfBase2);
|
||||||
|
base8: include(n.flags, nfBase8);
|
||||||
|
base16: include(n.flags, nfBase16);
|
||||||
|
end
|
||||||
|
end;
|
||||||
|
|
||||||
function identOrLiteral(var p: TParser): PNode;
|
function identOrLiteral(var p: TParser): PNode;
|
||||||
begin
|
begin
|
||||||
case p.tok.tokType of
|
case p.tok.tokType of
|
||||||
|
|
@ -530,42 +571,42 @@ begin
|
||||||
// literals
|
// literals
|
||||||
tkIntLit: begin
|
tkIntLit: begin
|
||||||
result := newIntNodeP(nkIntLit, p.tok.iNumber, p);
|
result := newIntNodeP(nkIntLit, p.tok.iNumber, p);
|
||||||
result.base := p.tok.base;
|
setBaseFlags(result, p.tok.base);
|
||||||
getTok(p);
|
getTok(p);
|
||||||
end;
|
end;
|
||||||
tkInt8Lit: begin
|
tkInt8Lit: begin
|
||||||
result := newIntNodeP(nkInt8Lit, p.tok.iNumber, p);
|
result := newIntNodeP(nkInt8Lit, p.tok.iNumber, p);
|
||||||
result.base := p.tok.base;
|
setBaseFlags(result, p.tok.base);
|
||||||
getTok(p);
|
getTok(p);
|
||||||
end;
|
end;
|
||||||
tkInt16Lit: begin
|
tkInt16Lit: begin
|
||||||
result := newIntNodeP(nkInt16Lit, p.tok.iNumber, p);
|
result := newIntNodeP(nkInt16Lit, p.tok.iNumber, p);
|
||||||
result.base := p.tok.base;
|
setBaseFlags(result, p.tok.base);
|
||||||
getTok(p);
|
getTok(p);
|
||||||
end;
|
end;
|
||||||
tkInt32Lit: begin
|
tkInt32Lit: begin
|
||||||
result := newIntNodeP(nkInt32Lit, p.tok.iNumber, p);
|
result := newIntNodeP(nkInt32Lit, p.tok.iNumber, p);
|
||||||
result.base := p.tok.base;
|
setBaseFlags(result, p.tok.base);
|
||||||
getTok(p);
|
getTok(p);
|
||||||
end;
|
end;
|
||||||
tkInt64Lit: begin
|
tkInt64Lit: begin
|
||||||
result := newIntNodeP(nkInt64Lit, p.tok.iNumber, p);
|
result := newIntNodeP(nkInt64Lit, p.tok.iNumber, p);
|
||||||
result.base := p.tok.base;
|
setBaseFlags(result, p.tok.base);
|
||||||
getTok(p);
|
getTok(p);
|
||||||
end;
|
end;
|
||||||
tkFloatLit: begin
|
tkFloatLit: begin
|
||||||
result := newFloatNodeP(nkFloatLit, p.tok.fNumber, p);
|
result := newFloatNodeP(nkFloatLit, p.tok.fNumber, p);
|
||||||
result.base := p.tok.base;
|
setBaseFlags(result, p.tok.base);
|
||||||
getTok(p);
|
getTok(p);
|
||||||
end;
|
end;
|
||||||
tkFloat32Lit: begin
|
tkFloat32Lit: begin
|
||||||
result := newFloatNodeP(nkFloat32Lit, p.tok.fNumber, p);
|
result := newFloatNodeP(nkFloat32Lit, p.tok.fNumber, p);
|
||||||
result.base := p.tok.base;
|
setBaseFlags(result, p.tok.base);
|
||||||
getTok(p);
|
getTok(p);
|
||||||
end;
|
end;
|
||||||
tkFloat64Lit: begin
|
tkFloat64Lit: begin
|
||||||
result := newFloatNodeP(nkFloat64Lit, p.tok.fNumber, p);
|
result := newFloatNodeP(nkFloat64Lit, p.tok.fNumber, p);
|
||||||
result.base := p.tok.base;
|
setBaseFlags(result, p.tok.base);
|
||||||
getTok(p);
|
getTok(p);
|
||||||
end;
|
end;
|
||||||
tkStrLit: begin
|
tkStrLit: begin
|
||||||
|
|
@ -584,10 +625,6 @@ begin
|
||||||
result := newIntNodeP(nkCharLit, ord(p.tok.literal[strStart]), p);
|
result := newIntNodeP(nkCharLit, ord(p.tok.literal[strStart]), p);
|
||||||
getTok(p);
|
getTok(p);
|
||||||
end;
|
end;
|
||||||
tkRCharLit: begin
|
|
||||||
result := newIntNodeP(nkRCharLit, ord(p.tok.literal[strStart]), p);
|
|
||||||
getTok(p);
|
|
||||||
end;
|
|
||||||
tkNil: begin
|
tkNil: begin
|
||||||
result := newNodeP(nkNilLit, p);
|
result := newNodeP(nkNilLit, p);
|
||||||
getTok(p);
|
getTok(p);
|
||||||
|
|
@ -598,8 +635,7 @@ begin
|
||||||
tkColon);
|
tkColon);
|
||||||
end;
|
end;
|
||||||
tkCurlyLe: begin // {} constructor
|
tkCurlyLe: begin // {} constructor
|
||||||
result := exprColonEqExprList(p, nkCurly, nkRange, tkCurlyRi,
|
result := exprColonEqExprList(p, nkCurly, nkRange, tkCurlyRi, tkDotDot);
|
||||||
tkDotDot);
|
|
||||||
end;
|
end;
|
||||||
tkBracketLe: begin // [] constructor
|
tkBracketLe: begin // [] constructor
|
||||||
result := exprColonEqExprList(p, nkBracket, nkExprColonExpr, tkBracketRi,
|
result := exprColonEqExprList(p, nkBracket, nkExprColonExpr, tkBracketRi,
|
||||||
|
|
@ -1278,6 +1314,8 @@ begin
|
||||||
end;
|
end;
|
||||||
|
|
||||||
function parseTypeDescK(var p: TParser): PNode;
|
function parseTypeDescK(var p: TParser): PNode;
|
||||||
|
var
|
||||||
|
a: PNode;
|
||||||
begin
|
begin
|
||||||
case p.tok.tokType of
|
case p.tok.tokType of
|
||||||
tkVar: result := parseTypeDescKAux(p, nkVarTy);
|
tkVar: result := parseTypeDescKAux(p, nkVarTy);
|
||||||
|
|
@ -1298,7 +1336,25 @@ begin
|
||||||
addSon(result, parsePragma(p))
|
addSon(result, parsePragma(p))
|
||||||
else
|
else
|
||||||
addSon(result, nil);
|
addSon(result, nil);
|
||||||
end
|
end;
|
||||||
|
tkTuple: begin
|
||||||
|
result := newNodeP(nkTupleTy, p);
|
||||||
|
getTok(p);
|
||||||
|
eat(p, tkBracketLe);
|
||||||
|
optInd(p, result);
|
||||||
|
while true do begin
|
||||||
|
case p.tok.tokType of
|
||||||
|
tkSymbol, tkAccent: a := parseIdentColonEquals(p, false);
|
||||||
|
tkBracketRi: begin getTok(p); break end;
|
||||||
|
else begin parMessage(p, errTokenExpected, ']'+''); break; end;
|
||||||
|
end;
|
||||||
|
optInd(p, a);
|
||||||
|
if p.tok.tokType = tkComma then begin
|
||||||
|
getTok(p); optInd(p, a)
|
||||||
|
end;
|
||||||
|
addSon(result, a);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
else begin
|
else begin
|
||||||
InternalError(parLineInfo(p), 'pnimsyn.parseTypeDescK');
|
InternalError(parLineInfo(p), 'pnimsyn.parseTypeDescK');
|
||||||
result := nil
|
result := nil
|
||||||
|
|
@ -1309,7 +1365,7 @@ end;
|
||||||
function parseTypeDesc(var p: TParser): PNode;
|
function parseTypeDesc(var p: TParser): PNode;
|
||||||
begin
|
begin
|
||||||
case p.tok.tokType of
|
case p.tok.tokType of
|
||||||
tkVar, tkRef, tkPtr, tkProc, tkType:
|
tkVar, tkRef, tkPtr, tkProc, tkType, tkTuple:
|
||||||
result := parseTypeDescK(p);
|
result := parseTypeDescK(p);
|
||||||
else result := primary(p)
|
else result := primary(p)
|
||||||
end
|
end
|
||||||
|
|
@ -1599,7 +1655,7 @@ begin
|
||||||
if kind = nkObjectTy then
|
if kind = nkObjectTy then
|
||||||
addSon(result, a)
|
addSon(result, a)
|
||||||
else
|
else
|
||||||
parMessage(p, errInheritanceOnlyWithObjects);
|
parMessage(p, errInheritanceOnlyWithNonFinalObjects);
|
||||||
end
|
end
|
||||||
else addSon(result, nil);
|
else addSon(result, nil);
|
||||||
skipComment(p, result);
|
skipComment(p, result);
|
||||||
|
|
@ -1617,7 +1673,6 @@ begin
|
||||||
if p.tok.tokType = tkEquals then begin
|
if p.tok.tokType = tkEquals then begin
|
||||||
getTok(p); optInd(p, result);
|
getTok(p); optInd(p, result);
|
||||||
case p.tok.tokType of
|
case p.tok.tokType of
|
||||||
tkRecord: a := parseRecordOrObject(p, nkRecordTy);
|
|
||||||
tkObject: a := parseRecordOrObject(p, nkObjectTy);
|
tkObject: a := parseRecordOrObject(p, nkObjectTy);
|
||||||
tkEnum: a := parseEnum(p);
|
tkEnum: a := parseEnum(p);
|
||||||
else a := parseTypeDesc(p);
|
else a := parseTypeDesc(p);
|
||||||
|
|
@ -1671,6 +1726,7 @@ begin
|
||||||
tkIterator: result := parseRoutine(p, nkIteratorDef);
|
tkIterator: result := parseRoutine(p, nkIteratorDef);
|
||||||
tkMacro: result := parseRoutine(p, nkMacroDef);
|
tkMacro: result := parseRoutine(p, nkMacroDef);
|
||||||
tkTemplate: result := parseRoutine(p, nkTemplateDef);
|
tkTemplate: result := parseRoutine(p, nkTemplateDef);
|
||||||
|
tkConverter: result := parseRoutine(p, nkConverterDef);
|
||||||
tkType: result := parseSection(p, nkTypeSection, parseTypeDef);
|
tkType: result := parseSection(p, nkTypeSection, parseTypeDef);
|
||||||
tkConst: result := parseSection(p, nkConstSection, parseConstant);
|
tkConst: result := parseSection(p, nkConstSection, parseConstant);
|
||||||
tkWhen: result := parseIfOrWhen(p, nkWhenStmt);
|
tkWhen: result := parseIfOrWhen(p, nkWhenStmt);
|
||||||
|
|
|
||||||
|
|
@ -26,11 +26,10 @@ begin
|
||||||
if (it.kind = nkExprColonExpr) and (it.sons[0].kind = nkIdent) then begin
|
if (it.kind = nkExprColonExpr) and (it.sons[0].kind = nkIdent) then begin
|
||||||
case whichKeyword(it.sons[0].ident) of
|
case whichKeyword(it.sons[0].ident) of
|
||||||
wAsmQuote: begin
|
wAsmQuote: begin
|
||||||
case it.sons[1].kind of
|
if it.sons[1].kind = nkCharLit then
|
||||||
nkCharLit, nkRCharLit: result := chr(int(it.sons[1].intVal));
|
result := chr(int(it.sons[1].intVal))
|
||||||
else invalidPragma(it)
|
else invalidPragma(it)
|
||||||
end
|
end
|
||||||
end
|
|
||||||
else
|
else
|
||||||
invalidPragma(it)
|
invalidPragma(it)
|
||||||
end
|
end
|
||||||
|
|
@ -246,6 +245,8 @@ begin
|
||||||
sw := whichKeyword(n.sons[0].ident);
|
sw := whichKeyword(n.sons[0].ident);
|
||||||
case sw of
|
case sw of
|
||||||
wChecks: OnOff(c, n, checksOptions);
|
wChecks: OnOff(c, n, checksOptions);
|
||||||
|
wObjChecks: OnOff(c, n, {@set}[optObjCheck]);
|
||||||
|
wFieldchecks: OnOff(c, n, {@set}[optFieldCheck]);
|
||||||
wRangechecks: OnOff(c, n, {@set}[optRangeCheck]);
|
wRangechecks: OnOff(c, n, {@set}[optRangeCheck]);
|
||||||
wBoundchecks: OnOff(c, n, {@set}[optBoundsCheck]);
|
wBoundchecks: OnOff(c, n, {@set}[optBoundsCheck]);
|
||||||
wOverflowchecks: OnOff(c, n, {@set}[optOverflowCheck]);
|
wOverflowchecks: OnOff(c, n, {@set}[optOverflowCheck]);
|
||||||
|
|
@ -373,12 +374,12 @@ begin
|
||||||
end
|
end
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure Breakpoint(c: PContext; n: PNode);
|
procedure PragmaBreakpoint(c: PContext; n: PNode);
|
||||||
begin
|
begin
|
||||||
{@discard} getOptionalStr(c, n, '');
|
{@discard} getOptionalStr(c, n, '');
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure Checkpoint(c: PContext; n: PNode);
|
procedure PragmaCheckpoint(c: PContext; n: PNode);
|
||||||
// checkpoints can be used to debug the compiler; they are not documented
|
// checkpoints can be used to debug the compiler; they are not documented
|
||||||
var
|
var
|
||||||
info: TLineInfo;
|
info: TLineInfo;
|
||||||
|
|
@ -427,7 +428,10 @@ begin
|
||||||
liMessage(it.info, errPowerOfTwoExpected);
|
liMessage(it.info, errPowerOfTwoExpected);
|
||||||
end;
|
end;
|
||||||
wNodecl: begin noVal(it); Include(sym.loc.Flags, lfNoDecl); end;
|
wNodecl: begin noVal(it); Include(sym.loc.Flags, lfNoDecl); end;
|
||||||
wPure: begin noVal(it); include(sym.flags, sfPure); end;
|
wPure: begin
|
||||||
|
noVal(it);
|
||||||
|
if sym <> nil then include(sym.flags, sfPure);
|
||||||
|
end;
|
||||||
wVolatile: begin noVal(it); Include(sym.flags, sfVolatile); end;
|
wVolatile: begin noVal(it); Include(sym.flags, sfVolatile); end;
|
||||||
wRegister: begin noVal(it); include(sym.flags, sfRegister); end;
|
wRegister: begin noVal(it); include(sym.flags, sfRegister); end;
|
||||||
wMagic: processMagic(c, it, sym);
|
wMagic: processMagic(c, it, sym);
|
||||||
|
|
@ -444,7 +448,6 @@ begin
|
||||||
wNosideeffect: begin noVal(it); Include(sym.flags, sfNoSideEffect); end;
|
wNosideeffect: begin noVal(it); Include(sym.flags, sfNoSideEffect); end;
|
||||||
wNoReturn: begin noVal(it); Include(sym.flags, sfNoReturn); end;
|
wNoReturn: begin noVal(it); Include(sym.flags, sfNoReturn); end;
|
||||||
wDynLib: processDynLib(c, it, sym);
|
wDynLib: processDynLib(c, it, sym);
|
||||||
wReturnsNew: begin noVal(it); Include(sym.flags, sfReturnsNew); end;
|
|
||||||
wCompilerProc: begin
|
wCompilerProc: begin
|
||||||
noVal(it); // compilerproc may not get a string!
|
noVal(it); // compilerproc may not get a string!
|
||||||
makeExternExport(sym, sym.name.s);
|
makeExternExport(sym, sym.name.s);
|
||||||
|
|
@ -464,6 +467,14 @@ begin
|
||||||
noVal(it);
|
noVal(it);
|
||||||
include(sym.typ.flags, tfVarargs);
|
include(sym.typ.flags, tfVarargs);
|
||||||
end;
|
end;
|
||||||
|
wFinal: begin
|
||||||
|
noVal(it);
|
||||||
|
include(sym.typ.flags, tfFinal);
|
||||||
|
end;
|
||||||
|
wTypeCheck: begin
|
||||||
|
noVal(it);
|
||||||
|
include(sym.flags, sfTypeCheck);
|
||||||
|
end;
|
||||||
|
|
||||||
// statement pragmas:
|
// statement pragmas:
|
||||||
wHint: liMessage(it.info, hintUser, expectStrLit(c, it));
|
wHint: liMessage(it.info, hintUser, expectStrLit(c, it));
|
||||||
|
|
@ -478,6 +489,9 @@ begin
|
||||||
wCompile: processCompile(c, it);
|
wCompile: processCompile(c, it);
|
||||||
wLink: processCommonLink(c, it, linkNormal);
|
wLink: processCommonLink(c, it, linkNormal);
|
||||||
wLinkSys: processCommonLink(c, it, linkSys);
|
wLinkSys: processCommonLink(c, it, linkSys);
|
||||||
|
wPassL: extccomp.addLinkOption(expectStrLit(c, it));
|
||||||
|
wPassC: extccomp.addCompileOption(expectStrLit(c, it));
|
||||||
|
|
||||||
// fixupSystem not even documented:
|
// fixupSystem not even documented:
|
||||||
wFixupSystem: begin
|
wFixupSystem: begin
|
||||||
if c.module = magicSys.SystemModule then
|
if c.module = magicSys.SystemModule then
|
||||||
|
|
@ -485,12 +499,13 @@ begin
|
||||||
else
|
else
|
||||||
invalidPragma(it)
|
invalidPragma(it)
|
||||||
end;
|
end;
|
||||||
wBreakpoint: Breakpoint(c, it);
|
wBreakpoint: PragmaBreakpoint(c, it);
|
||||||
wCheckpoint: Checkpoint(c, it);
|
wCheckpoint: PragmaCheckpoint(c, it);
|
||||||
|
|
||||||
wPush: begin processPush(c, n, i+1); break end;
|
wPush: begin processPush(c, n, i+1); break end;
|
||||||
wPop: processPop(c, it);
|
wPop: processPop(c, it);
|
||||||
wChecks, wRangechecks, wBoundchecks, wOverflowchecks, wNilchecks,
|
wChecks, wObjChecks, wFieldChecks,
|
||||||
|
wRangechecks, wBoundchecks, wOverflowchecks, wNilchecks,
|
||||||
wAssertions, wWarnings, wHints, wLinedir, wStacktrace,
|
wAssertions, wWarnings, wHints, wLinedir, wStacktrace,
|
||||||
wLinetrace, wOptimization, wByRef, wCallConv, wDebugger:
|
wLinetrace, wOptimization, wByRef, wCallConv, wDebugger:
|
||||||
processOption(c, it);
|
processOption(c, it);
|
||||||
|
|
@ -528,20 +543,28 @@ begin
|
||||||
wCppMethod, wDeprecated, wVarargs]);
|
wCppMethod, wDeprecated, wVarargs]);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure pragmaMacro(c: PContext; s: PSym; n: PNode);
|
||||||
|
begin
|
||||||
|
pragma(c, s, n, {@set}[FirstCallConv..LastCallConv,
|
||||||
|
wImportc, wExportc, wNostatic, wNodecl, wMagic, wNosideEffect,
|
||||||
|
wCompilerProc, wDeprecated, wTypeCheck]);
|
||||||
|
end;
|
||||||
|
|
||||||
procedure pragmaIterator(c: PContext; s: PSym; n: PNode);
|
procedure pragmaIterator(c: PContext; s: PSym; n: PNode);
|
||||||
begin
|
begin
|
||||||
pragma(c, s, n, {@set}[FirstCallConv..LastCallConv,
|
pragma(c, s, n, {@set}[FirstCallConv..LastCallConv,
|
||||||
wImportc, wExportc, wNodecl, wMagic, wDeprecated]);
|
wImportc, wExportc, wNodecl, wMagic, wDeprecated]);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure pragmaStmt(c: PContext; n: PNode);
|
procedure pragmaStmt(c: PContext; s: PSym; n: PNode);
|
||||||
begin
|
begin
|
||||||
pragma(c, nil, n, {@set}[wChecks, wRangechecks, wBoundchecks,
|
pragma(c, s, n, {@set}[wChecks, wObjChecks, wFieldChecks, wRangechecks,
|
||||||
wOverflowchecks, wNilchecks, wAssertions, wWarnings,
|
wBoundchecks, wOverflowchecks, wNilchecks, wAssertions, wWarnings,
|
||||||
wHints, wLinedir, wStacktrace, wLinetrace, wOptimization,
|
wHints, wLinedir, wStacktrace, wLinetrace, wOptimization,
|
||||||
wHint, wWarning, wError, wFatal, wDefine, wUndef,
|
wHint, wWarning, wError, wFatal, wDefine, wUndef,
|
||||||
wCompile, wLink, wLinkSys,
|
wCompile, wLink, wLinkSys, wPure,
|
||||||
wPush, wPop, wFixupSystem, wBreakpoint, wCheckpoint]);
|
wPush, wPop, wFixupSystem, wBreakpoint, wCheckpoint,
|
||||||
|
wPassL, wPassC]);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure pragmaLambda(c: PContext; s: PSym; n: PNode);
|
procedure pragmaLambda(c: PContext; s: PSym; n: PNode);
|
||||||
|
|
@ -554,7 +577,7 @@ end;
|
||||||
procedure pragmaType(c: PContext; s: PSym; n: PNode);
|
procedure pragmaType(c: PContext; s: PSym; n: PNode);
|
||||||
begin
|
begin
|
||||||
pragma(c, s, n, {@set}[wImportc, wExportc, wDeprecated, wMagic,
|
pragma(c, s, n, {@set}[wImportc, wExportc, wDeprecated, wMagic,
|
||||||
wNodecl, wPure, wHeader, wCompilerProc]);
|
wNodecl, wPure, wHeader, wCompilerProc, wFinal]);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
procedure pragmaField(c: PContext; s: PSym; n: PNode);
|
procedure pragmaField(c: PContext; s: PSym; n: PNode);
|
||||||
|
|
|
||||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue