diff options
author | Andreas Rumpf <rumpf_a@web.de> | 2009-06-24 17:13:22 +0200 |
---|---|---|
committer | Andreas Rumpf <rumpf_a@web.de> | 2009-06-24 17:13:22 +0200 |
commit | 300430fbba28b408f7ac86ca46b03d9d50839399 (patch) | |
tree | b8a84f8efdccda7bfa909b3db911d9e2b9a4b39b /doc | |
parent | 36818817bd61594ea6d106328bb8df0f5a25cfc4 (diff) | |
download | Nim-300430fbba28b408f7ac86ca46b03d9d50839399.tar.gz |
overload resolution for proc vars
Diffstat (limited to 'doc')
-rw-r--r-- | doc/grammar.txt | 6 | ||||
-rw-r--r-- | doc/manual.txt | 98 | ||||
-rw-r--r-- | doc/theindex.txt | 72 | ||||
-rw-r--r-- | doc/tut1.txt | 17 | ||||
-rw-r--r-- | doc/tut2.txt | 13 |
5 files changed, 144 insertions, 62 deletions
diff --git a/doc/grammar.txt b/doc/grammar.txt index 91ce6a911..8c3966387 100644 --- a/doc/grammar.txt +++ b/doc/grammar.txt @@ -29,8 +29,8 @@ addrExpr ::= 'addr' '(' optInd expr ')' symbol ::= '`' (KEYWORD | IDENT | operator | '(' ')' | '[' ']' | '=' | literal)+ '`' | IDENT -primary ::= (prefixOperator optInd)* (symbol | constructor | - castExpr | addrExpr) ( +primary ::= ((prefixOperator | 'bind') optInd)* (symbol | constructor | + castExpr | addrExpr) ( '.' optInd symbol | '(' optInd namedExprList [SAD] ')' | '[' optInd @@ -42,7 +42,7 @@ primary ::= (prefixOperator optInd)* (symbol | constructor | literal ::= INT_LIT | INT8_LIT | INT16_LIT | INT32_LIT | INT64_LIT | FLOAT_LIT | FLOAT32_LIT | FLOAT64_LIT | STR_LIT | RSTR_LIT | TRIPLESTR_LIT - | CHAR_LIT | RCHAR_LIT + | CHAR_LIT | NIL constructor ::= literal diff --git a/doc/manual.txt b/doc/manual.txt index 8b7e264ad..1c7eb01b7 100644 --- a/doc/manual.txt +++ b/doc/manual.txt @@ -336,7 +336,7 @@ Precedence level Operators First characte The grammar's start symbol is ``module``. The grammar is LL(1) and therefore -not ambigious. +not ambiguous. .. include:: grammar.txt :literal: @@ -920,6 +920,95 @@ each other: Most calling conventions exist only for the Windows 32-bit platform. +Type relations +-------------- + +The following section defines several relations on types that are needed to +describe the type checking done by the compiler. + + +Type equality +~~~~~~~~~~~~~ +Nimrod uses structural type equivalence for most types. Only for objects, +enumerations and abstract types name equivalence is used. The following +algorithm determines type equality: + +.. code-block:: nimrod + proc typeEqualsAux(a, b: PType, + s: var set[tuple[PType, PType]]): bool = + if (a,b) in s: return true + incl(s, (a,b)) + if a.kind == b.kind: + case a.kind + of int, intXX, float, floatXX, char, string, cstring, pointer, bool, nil: + # leaf type: kinds identical; nothing more to check + result = true + of ref, ptr, var, set, seq, openarray: + result = typeEqualsAux(a.baseType, b.baseType, s) + of range: + result = typeEqualsAux(a.baseType, b.baseType, s) and + (a.rangeA == b.rangeA) and (a.rangeB == b.rangeB) + of array: + result = typeEqualsAux(a.baseType, b.baseType, s) and + typeEqualsAux(a.indexType, b.indexType, s) + of tuple: + if a.tupleLen == b.tupleLen: + for i in 0..a.tupleLen-1: + if not typeEqualsAux(a[i], b[i], s): return false + result = true + of object, enum, abstract: + result = a == b + of proc: + result = typeEqualsAux(a.parameterTuple, b.parameterTuple, s) and + typeEqualsAux(a.resultType, b.resultType, s) and + a.callingConvention == b.callingConvention + + proc typeEquals(a, b: PType): bool = + var s: set[tuple[PType, PType]] = {} + result = typeEqualsAux(a, b, s) + +Since types are graphs which can have cycles, the above algorithm needs an +auxiliary set ``s`` to detect this case. + + +Subtype relation +~~~~~~~~~~~~~~~~ +If object ``b`` inherits from ``a``, ``b`` is a subtype of ``a``. This subtype +relation is extended to the types ``var``, ``ref``, ``ptr``: + +.. code-block:: nimrod + proc isSubtype(a, b: PType): bool = + if a.kind == b.kind: + case a.kind + of object: + var aa = a.baseType + while aa != nil and aa != b: aa = aa.baseType + result = aa == b + of var, ref, ptr: + result = isSubtype(a.baseType, b.baseType) + +XXX nil is a special value! + + +Convertible relation +~~~~~~~~~~~~~~~~~~~~ +A type ``a`` is convertible to type ``b`` iff the following algorithm returns +true: + +.. code-block:: nimrod + proc isConvertible(a, b: PType): bool = + if a.kind == b.kind: + case a.kind + of proc: + var x = a.parameterTuple + var y = b.parameterTuple + if x.tupleLen == y.tupleLen: + for i in 0.. x.tupleLen-1: + if not isSubtype(x[i], y[i]): return false + result = isSubType(b.resultType, a.resultType) + + + Statements and expressions -------------------------- @@ -927,8 +1016,7 @@ Nimrod uses the common statement/expression paradigm: `Statements`:idx: do not produce a value in contrast to expressions. Call expressions are statements. If the called procedure returns a value, it is not a valid statement as statements do not produce values. To evaluate an expression for -side-effects and throwing its value away, one can use the ``discard`` -statement. +side-effects and throw its value away, one can use the ``discard`` statement. Statements are separated into `simple statements`:idx: and `complex statements`:idx:. @@ -1917,11 +2005,11 @@ iterator in which case the overloading resolution takes place: # Module C import A, B - write(stdout, x) # error: x is ambigious + write(stdout, x) # error: x is ambiguous write(stdout, A.x) # no error: qualifier used var x = 4 - write(stdout, x) # not ambigious: uses the module C's x + write(stdout, x) # not ambiguous: uses the module C's x Messages diff --git a/doc/theindex.txt b/doc/theindex.txt index b5650e1be..81bcf9c67 100644 --- a/doc/theindex.txt +++ b/doc/theindex.txt @@ -155,6 +155,9 @@ Index * `system.html#314 <system.html#314>`_ `<=`:idx: + `times.html#115 <times.html#115>`_ + + `<=`:idx: * `system.html#253 <system.html#253>`_ * `system.html#254 <system.html#254>`_ * `system.html#255 <system.html#255>`_ @@ -169,9 +172,6 @@ Index * `system.html#345 <system.html#345>`_ * `system.html#346 <system.html#346>`_ - `<=`:idx: - `times.html#115 <times.html#115>`_ - `<=%`:idx: * `system.html#305 <system.html#305>`_ * `system.html#306 <system.html#306>`_ @@ -201,7 +201,7 @@ Index * `macros.html#117 <macros.html#117>`_ `=~`:idx: - `regexprs.html#111 <regexprs.html#111>`_ + `regexprs.html#108 <regexprs.html#108>`_ `>`:idx: `system.html#357 <system.html#357>`_ @@ -219,16 +219,16 @@ Index `system.html#365 <system.html#365>`_ `[]`:idx: - `strtabs.html#107 <strtabs.html#107>`_ + `macros.html#113 <macros.html#113>`_ `[]`:idx: - `macros.html#113 <macros.html#113>`_ + `strtabs.html#107 <strtabs.html#107>`_ `[]=`:idx: - `macros.html#114 <macros.html#114>`_ + `strtabs.html#106 <strtabs.html#106>`_ `[]=`:idx: - `strtabs.html#106 <strtabs.html#106>`_ + `macros.html#114 <macros.html#114>`_ `[ESC]`:idx: `manual.html#134 <manual.html#134>`_ @@ -366,8 +366,7 @@ Index `xmlgen.html#111 <xmlgen.html#111>`_ `backslash`:idx: - * `manual.html#127 <manual.html#127>`_ - * `regexprs.html#101 <regexprs.html#101>`_ + `manual.html#127 <manual.html#127>`_ `backspace`:idx: `manual.html#132 <manual.html#132>`_ @@ -1228,7 +1227,7 @@ Index `system.html#156 <system.html#156>`_ `EInvalidRegEx`:idx: - `regexprs.html#104 <regexprs.html#104>`_ + `regexprs.html#101 <regexprs.html#101>`_ `EInvalidValue`:idx: `system.html#148 <system.html#148>`_ @@ -1265,12 +1264,12 @@ Index `enum_cursor_type`:idx: `mysql.html#237 <mysql.html#237>`_ - `Enumeration`:idx: - `manual.html#148 <manual.html#148>`_ - `enumeration`:idx: `tut1.html#113 <tut1.html#113>`_ + `Enumeration`:idx: + `manual.html#148 <manual.html#148>`_ + `enum_field_types`:idx: `mysql.html#202 <mysql.html#202>`_ @@ -1546,8 +1545,8 @@ Index * `strutils.html#124 <strutils.html#124>`_ * `strutils.html#125 <strutils.html#125>`_ * `strutils.html#126 <strutils.html#126>`_ - * `regexprs.html#109 <regexprs.html#109>`_ - * `regexprs.html#110 <regexprs.html#110>`_ + * `regexprs.html#106 <regexprs.html#106>`_ + * `regexprs.html#107 <regexprs.html#107>`_ `findChars`:idx: `strutils.html#123 <strutils.html#123>`_ @@ -1631,9 +1630,6 @@ Index * `system.html#478 <system.html#478>`_ * `system.html#479 <system.html#479>`_ - `generic character types`:idx: - `regexprs.html#102 <regexprs.html#102>`_ - `Generics`:idx: * `manual.html#207 <manual.html#207>`_ * `tut2.html#108 <tut2.html#108>`_ @@ -2258,11 +2254,11 @@ Index `xmlgen.html#150 <xmlgen.html#150>`_ `match`:idx: - * `regexprs.html#106 <regexprs.html#106>`_ - * `regexprs.html#107 <regexprs.html#107>`_ + * `regexprs.html#103 <regexprs.html#103>`_ + * `regexprs.html#104 <regexprs.html#104>`_ `matchLen`:idx: - `regexprs.html#108 <regexprs.html#108>`_ + `regexprs.html#105 <regexprs.html#105>`_ `math`:idx: `nimrodc.html#118 <nimrodc.html#118>`_ @@ -2301,7 +2297,7 @@ Index `mysql.html#191 <mysql.html#191>`_ `MaxSubpatterns`:idx: - `regexprs.html#105 <regexprs.html#105>`_ + `regexprs.html#102 <regexprs.html#102>`_ `MAX_TINYINT_WIDTH`:idx: `mysql.html#190 <mysql.html#190>`_ @@ -3095,12 +3091,12 @@ Index `ord`:idx: `system.html#172 <system.html#172>`_ - `ordinal`:idx: - `tut1.html#114 <tut1.html#114>`_ - `Ordinal`:idx: `system.html#114 <system.html#114>`_ + `ordinal`:idx: + `tut1.html#114 <tut1.html#114>`_ + `Ordinal types`:idx: `manual.html#141 <manual.html#141>`_ @@ -3623,16 +3619,16 @@ Index `system.html#419 <system.html#419>`_ `reBinary`:idx: - `regexprs.html#116 <regexprs.html#116>`_ + `regexprs.html#113 <regexprs.html#113>`_ `Recursive module dependancies`:idx: `manual.html#216 <manual.html#216>`_ `reEmail`:idx: - `regexprs.html#119 <regexprs.html#119>`_ + `regexprs.html#116 <regexprs.html#116>`_ `reFloat`:idx: - `regexprs.html#118 <regexprs.html#118>`_ + `regexprs.html#115 <regexprs.html#115>`_ `REFRESH_DES_KEY_FILE`:idx: `mysql.html#154 <mysql.html#154>`_ @@ -3680,13 +3676,13 @@ Index `nimrodc.html#112 <nimrodc.html#112>`_ `reHex`:idx: - `regexprs.html#115 <regexprs.html#115>`_ + `regexprs.html#112 <regexprs.html#112>`_ `reIdentifier`:idx: - `regexprs.html#112 <regexprs.html#112>`_ + `regexprs.html#109 <regexprs.html#109>`_ `reInteger`:idx: - `regexprs.html#114 <regexprs.html#114>`_ + `regexprs.html#111 <regexprs.html#111>`_ `removeDir`:idx: `os.html#150 <os.html#150>`_ @@ -3695,10 +3691,10 @@ Index `os.html#141 <os.html#141>`_ `reNatural`:idx: - `regexprs.html#113 <regexprs.html#113>`_ + `regexprs.html#110 <regexprs.html#110>`_ `reOctal`:idx: - `regexprs.html#117 <regexprs.html#117>`_ + `regexprs.html#114 <regexprs.html#114>`_ `repeatChar`:idx: `strutils.html#148 <strutils.html#148>`_ @@ -3724,7 +3720,7 @@ Index `manual.html#189 <manual.html#189>`_ `reURL`:idx: - `regexprs.html#120 <regexprs.html#120>`_ + `regexprs.html#117 <regexprs.html#117>`_ `round`:idx: `math.html#121 <math.html#121>`_ @@ -3889,9 +3885,6 @@ Index * `system.html#226 <system.html#226>`_ * `system.html#227 <system.html#227>`_ - `simple assertions`:idx: - `regexprs.html#103 <regexprs.html#103>`_ - `simple statements`:idx: `manual.html#174 <manual.html#174>`_ @@ -5154,6 +5147,9 @@ Index * `manual.html#156 <manual.html#156>`_ * `tut2.html#103 <tut2.html#103>`_ + `verbose`:idx: + `regexprs.html#118 <regexprs.html#118>`_ + `vertical tabulator`:idx: `manual.html#126 <manual.html#126>`_ diff --git a/doc/tut1.txt b/doc/tut1.txt index 237663cdc..bf744b885 100644 --- a/doc/tut1.txt +++ b/doc/tut1.txt @@ -264,7 +264,7 @@ For integers or other ordinal types value ranges are also possible: However, the above code does not compile: The reason is that you have to cover every value that ``n`` may contain, but the code only handles the values ``0..8``. Since it is not very practical to list every other possible integer -(though it is possible thanks to the range notation!), we fix this by telling +(though it is possible thanks to the range notation), we fix this by telling the compiler that for every other value nothing should be done: .. code-block:: nimrod @@ -624,7 +624,8 @@ Nimrod provides the ability to overload procedures similar to C++: .. code-block:: nimrod proc toString(x: int): string = ... proc toString(x: bool): string = - if x: return "true" else: return "false" + if x: return "true" + else: return "false" Echo(toString(13)) # calls the toString(x: int) proc Echo(toString(true)) # calls the toString(x: bool) proc @@ -634,7 +635,7 @@ The compiler chooses the most appropriate proc for the ``toString`` calls. How this overloading resolution algorithm works exactly is not discussed here (it will be specified in the manual soon). However, it does not lead to nasty suprises and is based on a quite simple -unification algorithm. Ambigious calls are reported as errors. +unification algorithm. Ambiguous calls are reported as errors. Operators @@ -643,7 +644,7 @@ The Nimrod library makes heavy use of overloading - one reason for this is that each operator like ``+`` is a just an overloaded proc. The parser lets you use operators in `infix notation` (``a + b``) or `prefix notation` (``+ a``). An infix operator always receives two arguments, a prefix operator always one. -Postfix operators are not possible, because this would be ambigious: Does +Postfix operators are not possible, because this would be ambiguous: Does ``a @ @ b`` mean ``(a) @ (@b)`` or ``(a@) @ (b)``? It always means ``(a) @ (@b)``, because there are no postfix operators in Nimrod. @@ -1331,7 +1332,7 @@ This is best illustrated by an example: A symbol of a module *can* be *qualified* with the ``module.symbol`` syntax. If -the symbol is ambigious, it even *has* to be qualified. A symbol is ambigious +the symbol is ambiguous, it even *has* to be qualified. A symbol is ambiguous if it is defined in two (or more) different modules and both modules are imported by a third one: @@ -1344,11 +1345,11 @@ imported by a third one: # Module C import A, B - write(stdout, x) # error: x is ambigious + write(stdout, x) # error: x is ambiguous write(stdout, A.x) # no error: qualifier used var x = 4 - write(stdout, x) # not ambigious: uses the module C's x + write(stdout, x) # not ambiguous: uses the module C's x But this rule does not apply to procedures or iterators. Here the overloading @@ -1367,7 +1368,7 @@ rules apply: write(stdout, x("")) # no error: B.x is called proc x*(a: int): string = nil - write(stdout, x(3)) # ambigious: which `x` is to call? + write(stdout, x(3)) # ambiguous: which `x` is to call? From statement diff --git a/doc/tut2.txt b/doc/tut2.txt index bb0949659..df6cc1b51 100644 --- a/doc/tut2.txt +++ b/doc/tut2.txt @@ -34,7 +34,7 @@ While Nimrod's support for object oriented programming (OOP) is minimalistic, powerful OOP technics can be used. OOP is seen as *one* way to design a program, not *the only* way. Often a procedural approach leads to simpler and more efficient code. In particular, prefering aggregation over inheritance -often results in a better design. +is often the better design. Objects @@ -446,8 +446,7 @@ containers: # this uses an explicit stack (which is more efficient anyway): var stack: seq[PBinaryTree[T]] = @[root] while stack.len > 0: - var n = stack[stack.len-1] - setLen(stack, stack.len-1) # pop `n` of the stack + var n = stack.pop() while n != nil: yield n add(stack, n.ri) # push right subtree onto the stack @@ -562,11 +561,11 @@ via a special ``:`` syntax: block: var fn = filename var f: TFile - if openFile(f, fn, mode): + if open(f, fn, mode): try: actions finally: - closeFile(f) + close(f) else: quit("cannot open: " & fn) @@ -593,9 +592,7 @@ Macros enable advanced compile-time code tranformations, but they cannot change Nimrod's syntax. However, this is no real restriction because Nimrod's syntax is flexible enough anyway. -`Macros`:idx: can be used to implement `domain specific languages`:idx:. - -To write macros, one needs to know how the Nimrod concrete syntax is converted +To write a macro, one needs to know how the Nimrod concrete syntax is converted to an abstract syntax tree (AST). The AST is documented in the `macros <macros.html>`_ module. |