summary refs log tree commit diff stats
path: root/doc/pydoc/ranger.container.commandlist.html
blob: 095138b694ddaccfca314572a9266c4ad46b0aa0 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html><head><title>Python: module ranger.container.commandlist</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head><body bgcolor="#f0f0f8">

<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="heading">
<tr bgcolor="#7799ee">
<td valign=bottom>&nbsp;<br>
<font color="#ffffff" face="helvetica, arial">&nbsp;<br><big><big><strong><a href="ranger.html"><font color="#ffffff">ranger</font></a>.<a href="ranger.container.html"><font color="#ffffff">container</font></a>.commandlist</strong></big></big></font></td
><td align=right valign=bottom
><font color="#ffffff" face="helvetica, arial"><a href=".">index</a><br><a href="file:/home/hut/work/ranger/ranger/container/commandlist.py">/home/hut/work/ranger/ranger/container/commandlist.py</a></font></td></tr></table>
    <p><tt>#&nbsp;Copyright&nbsp;(c)&nbsp;2009,&nbsp;2010&nbsp;hut&nbsp;&lt;hut@lavabit.com&gt;<br>
#<br>
#&nbsp;Permission&nbsp;to&nbsp;use,&nbsp;copy,&nbsp;modify,&nbsp;and/or&nbsp;distribute&nbsp;this&nbsp;software&nbsp;for&nbsp;any<br>
#&nbsp;purpose&nbsp;with&nbsp;or&nbsp;without&nbsp;fee&nbsp;is&nbsp;hereby&nbsp;granted,&nbsp;provided&nbsp;that&nbsp;the&nbsp;above<br>
#&nbsp;copyright&nbsp;notice&nbsp;and&nbsp;this&nbsp;permission&nbsp;notice&nbsp;appear&nbsp;in&nbsp;all&nbsp;copies.<br>
#<br>
#&nbsp;THE&nbsp;SOFTWARE&nbsp;IS&nbsp;PROVIDED&nbsp;"AS&nbsp;IS"&nbsp;AND&nbsp;THE&nbsp;AUTHOR&nbsp;DISCLAIMS&nbsp;ALL&nbsp;WARRANTIES<br>
#&nbsp;WITH&nbsp;REGARD&nbsp;TO&nbsp;THIS&nbsp;SOFTWARE&nbsp;INCLUDING&nbsp;ALL&nbsp;IMPLIED&nbsp;WARRANTIES&nbsp;OF<br>
#&nbsp;MERCHANTABILITY&nbsp;AND&nbsp;FITNESS.&nbsp;IN&nbsp;NO&nbsp;EVENT&nbsp;SHALL&nbsp;THE&nbsp;AUTHOR&nbsp;BE&nbsp;LIABLE&nbsp;FOR<br>
#&nbsp;ANY&nbsp;SPECIAL,&nbsp;DIRECT,&nbsp;INDIRECT,&nbsp;OR&nbsp;CONSEQUENTIAL&nbsp;DAMAGES&nbsp;OR&nbsp;ANY&nbsp;DAMAGES<br>
#&nbsp;WHATSOEVER&nbsp;RESULTING&nbsp;FROM&nbsp;LOSS&nbsp;OF&nbsp;USE,&nbsp;DATA&nbsp;OR&nbsp;PROFITS,&nbsp;WHETHER&nbsp;IN&nbsp;AN<br>
#&nbsp;ACTION&nbsp;OF&nbsp;CONTRACT,&nbsp;NEGLIGENCE&nbsp;OR&nbsp;OTHER&nbsp;TORTIOUS&nbsp;ACTION,&nbsp;ARISING&nbsp;OUT&nbsp;OF<br>
#&nbsp;OR&nbsp;IN&nbsp;CONNECTION&nbsp;WITH&nbsp;THE&nbsp;USE&nbsp;OR&nbsp;PERFORMANCE&nbsp;OF&nbsp;THIS&nbsp;SOFTWARE.</tt></p>
<p>
<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
<tr bgcolor="#ee77aa">
<td colspan=3 valign=bottom>&nbsp;<br>
<font color="#ffffff" face="helvetica, arial"><big><strong>Classes</strong></big></font></td></tr>
    
<tr><td bgcolor="#ee77aa"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
<td width="100%"><dl>
<dt><font face="helvetica, arial"><a href="builtins.html#object">builtins.object</a>
</font></dt><dd>
<dl>
<dt><font face="helvetica, arial"><a href="ranger.container.commandlist.html#Command">Command</a>
</font></dt><dt><font face="helvetica, arial"><a href="ranger.container.commandlist.html#CommandArgument">CommandArgument</a>
</font></dt><dt><font face="helvetica, arial"><a href="ranger.container.commandlist.html#CommandList">CommandList</a>
</font></dt><dt><font face="helvetica, arial"><a href="ranger.container.commandlist.html#Hint">Hint</a>
</font></dt></dl>
</dd>
</dl>
 <p>
<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
<tr bgcolor="#ffc8d8">
<td colspan=3 valign=bottom>&nbsp;<br>
<font color="#000000" face="helvetica, arial"><a name="Command">class <strong>Command</strong></a>(<a href="builtins.html#object">builtins.object</a>)</font></td></tr>
    
<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
<td colspan=2><tt><a href="#Command">Command</a>&nbsp;objects&nbsp;store&nbsp;information&nbsp;about&nbsp;a&nbsp;command<br>&nbsp;</tt></td></tr>
<tr><td>&nbsp;</td>
<td width="100%">Methods defined here:<br>
<dl><dt><a name="Command-__init__"><strong>__init__</strong></a>(self, fnc, keys)</dt></dl>

<dl><dt><a name="Command-execute"><strong>execute</strong></a>(self, *args)</dt><dd><tt>Execute&nbsp;the&nbsp;command</tt></dd></dl>

<dl><dt><a name="Command-execute_wrap"><strong>execute_wrap</strong></a>(self, displayable)</dt></dl>

<hr>
Data descriptors defined here:<br>
<dl><dt><strong>__dict__</strong></dt>
<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
</dl>
<dl><dt><strong>__weakref__</strong></dt>
<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
</dl>
<hr>
Data and other attributes defined here:<br>
<dl><dt><strong>keys</strong> = []</dl>

</td></tr></table> <p>
<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
<tr bgcolor="#ffc8d8">
<td colspan=3 valign=bottom>&nbsp;<br>
<font color="#000000" face="helvetica, arial"><a name="CommandArgument">class <strong>CommandArgument</strong></a>(<a href="builtins.html#object">builtins.object</a>)</font></td></tr>
    
<tr><td bgcolor="#ffc8d8"><tt>&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
<td width="100%">Methods defined here:<br>
<dl><dt><a name="CommandArgument-__init__"><strong>__init__</strong></a>(self, fm, displayable, keybuffer)</dt></dl>

<hr>
Data descriptors defined here:<br>
<dl><dt><strong>__dict__</strong></dt>
<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
</dl>
<dl><dt><strong>__weakref__</strong></dt>
<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
</dl>
</td></tr></table> <p>
<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
<tr bgcolor="#ffc8d8">
<td colspan=3 valign=bottom>&nbsp;<br>
<font color="#000000" face="helvetica, arial"><a name="CommandList">class <strong>CommandList</strong></a>(<a href="builtins.html#object">builtins.object</a>)</font></td></tr>
    
<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
<td colspan=2><tt>CommandLists&nbsp;are&nbsp;dictionary-like&nbsp;objects&nbsp;which&nbsp;give&nbsp;you&nbsp;a&nbsp;command<br>
for&nbsp;a&nbsp;given&nbsp;key&nbsp;combination.&nbsp;&nbsp;CommandLists&nbsp;must&nbsp;be&nbsp;filled&nbsp;before&nbsp;use.<br>&nbsp;</tt></td></tr>
<tr><td>&nbsp;</td>
<td width="100%">Methods defined here:<br>
<dl><dt><a name="CommandList-__getitem__"><strong>__getitem__</strong></a>(self, key)</dt><dd><tt>Returns&nbsp;the&nbsp;command&nbsp;with&nbsp;the&nbsp;given&nbsp;key&nbsp;combination</tt></dd></dl>

<dl><dt><a name="CommandList-__init__"><strong>__init__</strong></a>(self)</dt></dl>

<dl><dt><a name="CommandList-bind"><strong>bind</strong></a>(self, fnc, *keys)</dt><dd><tt>create&nbsp;a&nbsp;<a href="#Command">Command</a>&nbsp;<a href="builtins.html#object">object</a>&nbsp;and&nbsp;assign&nbsp;it&nbsp;to&nbsp;the&nbsp;given&nbsp;key&nbsp;combinations.</tt></dd></dl>

<dl><dt><a name="CommandList-hint"><strong>hint</strong></a>(self, text, *keys)</dt><dd><tt>create&nbsp;a&nbsp;<a href="#Hint">Hint</a>&nbsp;<a href="builtins.html#object">object</a>&nbsp;and&nbsp;assign&nbsp;it&nbsp;to&nbsp;the&nbsp;given&nbsp;key&nbsp;combinations.</tt></dd></dl>

<dl><dt><a name="CommandList-rebuild_paths"><strong>rebuild_paths</strong></a>(self)</dt><dd><tt>Fill&nbsp;the&nbsp;path&nbsp;dictionary&nbsp;with&nbsp;dummie&nbsp;objects.<br>
We&nbsp;need&nbsp;to&nbsp;know&nbsp;when&nbsp;to&nbsp;clear&nbsp;the&nbsp;keybuffer&nbsp;(when&nbsp;a&nbsp;wrong&nbsp;key&nbsp;is&nbsp;pressed)<br>
and&nbsp;when&nbsp;to&nbsp;wait&nbsp;for&nbsp;the&nbsp;rest&nbsp;of&nbsp;the&nbsp;key&nbsp;combination.&nbsp;&nbsp;For&nbsp;"gg"&nbsp;we<br>
will&nbsp;assign&nbsp;"g"&nbsp;to&nbsp;a&nbsp;dummy&nbsp;which&nbsp;tells&nbsp;the&nbsp;program&nbsp;to&nbsp;do&nbsp;the&nbsp;latter<br>
and&nbsp;wait.</tt></dd></dl>

<dl><dt><a name="CommandList-remove_dummies"><strong>remove_dummies</strong></a>(self)</dt><dd><tt>Remove&nbsp;dummie&nbsp;objects&nbsp;in&nbsp;case&nbsp;you&nbsp;have&nbsp;to&nbsp;rebuild&nbsp;a&nbsp;path&nbsp;dictionary<br>
which&nbsp;already&nbsp;contains&nbsp;dummie&nbsp;objects.</tt></dd></dl>

<hr>
Data descriptors defined here:<br>
<dl><dt><strong>__dict__</strong></dt>
<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
</dl>
<dl><dt><strong>__weakref__</strong></dt>
<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
</dl>
<hr>
Data and other attributes defined here:<br>
<dl><dt><strong>commandlist</strong> = []</dl>

<dl><dt><strong>dummies_in_paths</strong> = False</dl>

<dl><dt><strong>dummy_object</strong> = None</dl>

<dl><dt><strong>paths</strong> = {}</dl>

</td></tr></table> <p>
<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
<tr bgcolor="#ffc8d8">
<td colspan=3 valign=bottom>&nbsp;<br>
<font color="#000000" face="helvetica, arial"><a name="Hint">class <strong>Hint</strong></a>(<a href="builtins.html#object">builtins.object</a>)</font></td></tr>
    
<tr bgcolor="#ffc8d8"><td rowspan=2><tt>&nbsp;&nbsp;&nbsp;</tt></td>
<td colspan=2><tt>Hints&nbsp;display&nbsp;text&nbsp;without&nbsp;clearing&nbsp;the&nbsp;keybuffer<br>&nbsp;</tt></td></tr>
<tr><td>&nbsp;</td>
<td width="100%">Methods defined here:<br>
<dl><dt><a name="Hint-__init__"><strong>__init__</strong></a>(self, text, keys)</dt></dl>

<hr>
Data descriptors defined here:<br>
<dl><dt><strong>__dict__</strong></dt>
<dd><tt>dictionary&nbsp;for&nbsp;instance&nbsp;variables&nbsp;(if&nbsp;defined)</tt></dd>
</dl>
<dl><dt><strong>__weakref__</strong></dt>
<dd><tt>list&nbsp;of&nbsp;weak&nbsp;references&nbsp;to&nbsp;the&nbsp;object&nbsp;(if&nbsp;defined)</tt></dd>
</dl>
<hr>
Data and other attributes defined here:<br>
<dl><dt><strong>keys</strong> = []</dl>

<dl><dt><strong>text</strong> = ''</dl>

</td></tr></table></td></tr></table><p>
<table width="100%" cellspacing=0 cellpadding=2 border=0 summary="section">
<tr bgcolor="#eeaa77">
<td colspan=3 valign=bottom>&nbsp;<br>
<font color="#ffffff" face="helvetica, arial"><big><strong>Functions</strong></big></font></td></tr>
    
<tr><td bgcolor="#eeaa77"><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></td><td>&nbsp;</td>
<td width="100%"><dl><dt><a name="-cmdarg"><strong>cmdarg</strong></a>(displayable)</dt></dl>
</td></tr></table>
</body></html>
ass="w"> {nkCharLit..nkInt64Lit}: result = a.intVal <= b.intVal of nkFloatLit..nkFloat64Lit: if b.kind in {nkFloatLit..nkFloat64Lit}: result = a.floatVal <= b.floatVal of nkStrLit..nkTripleStrLit: if b.kind in {nkStrLit..nkTripleStrLit}: result = a.strVal <= b.strVal else: # don't raise an internal error for 'nimrod check': #InternalError(a.info, "leValue") nil proc lookupInRecord(n: PNode, field: PIdent): PSym = result = nil case n.kind of nkRecList: for i in countup(0, sonsLen(n) - 1): result = lookupInRecord(n.sons[i], field) if result != nil: return of nkRecCase: if (n.sons[0].kind != nkSym): InternalError(n.info, "lookupInRecord") result = lookupInRecord(n.sons[0], field) if result != nil: return for i in countup(1, sonsLen(n) - 1): case n.sons[i].kind of nkOfBranch, nkElse: result = lookupInRecord(lastSon(n.sons[i]), field) if result != nil: return else: internalError(n.info, "lookupInRecord(record case branch)") of nkSym: if n.sym.name.id == field.id: result = n.sym else: internalError(n.info, "lookupInRecord()") proc getModule(s: PSym): PSym = result = s assert((result.kind == skModule) or (result.owner != result)) while (result != nil) and (result.kind != skModule): result = result.owner proc getSymFromList(list: PNode, ident: PIdent, start: int = 0): PSym = for i in countup(start, sonsLen(list) - 1): if list.sons[i].kind == nkSym: result = list.sons[i].sym if result.name.id == ident.id: return else: InternalError(list.info, "getSymFromList") result = nil proc hashNode(p: PObject): THash = result = hash(cast[pointer](p)) proc mustRehash(length, counter: int): bool = assert(length > counter) result = (length * 2 < counter * 3) or (length - counter < 4) proc spaces(x: int): PRope = # returns x spaces result = toRope(repeatChar(x)) proc toYamlChar(c: Char): string = case c of '\0'..'\x1F', '\x80'..'\xFF': result = "\\u" & strutils.toHex(ord(c), 4) of '\'', '\"', '\\': result = '\\' & c else: result = $c proc makeYamlString*(s: string): PRope = # We have to split long strings into many ropes. Otherwise # this could trigger InternalError(111). See the ropes module for # further information. const MaxLineLength = 64 result = nil var res = "\"" for i in countup(0, len(s) - 1): if (i + 1) mod MaxLineLength == 0: add(res, '\"') add(res, "\n") app(result, toRope(res)) res = "\"" # reset add(res, toYamlChar(s[i])) add(res, '\"') app(result, toRope(res)) proc flagsToStr[T](flags: set[T]): PRope = if flags == {}: result = toRope("[]") else: result = nil for x in items(flags): if result != nil: app(result, ", ") app(result, makeYamlString($x)) result = con("[", con(result, "]")) proc lineInfoToStr(info: TLineInfo): PRope = result = ropef("[$1, $2, $3]", [makeYamlString(toFilename(info)), toRope(toLinenumber(info)), toRope(toColumn(info))]) proc treeToYamlAux(n: PNode, marker: var TIntSet, indent, maxRecDepth: int): PRope proc symToYamlAux(n: PSym, marker: var TIntSet, indent, maxRecDepth: int): PRope proc typeToYamlAux(n: PType, marker: var TIntSet, indent, maxRecDepth: int): PRope proc strTableToYaml(n: TStrTable, marker: var TIntSet, indent: int, maxRecDepth: int): PRope = var istr = spaces(indent + 2) result = toRope("[") var mycount = 0 for i in countup(0, high(n.data)): if n.data[i] != nil: if mycount > 0: app(result, ",") appf(result, "$N$1$2", [istr, symToYamlAux(n.data[i], marker, indent + 2, maxRecDepth - 1)]) inc(mycount) if mycount > 0: appf(result, "$N$1", [spaces(indent)]) app(result, "]") assert(mycount == n.counter) proc ropeConstr(indent: int, c: openarray[PRope]): PRope = # array of (name, value) pairs var istr = spaces(indent + 2) result = toRope("{") var i = 0 while i <= high(c): if i > 0: app(result, ",") appf(result, "$N$1\"$2\": $3", [istr, c[i], c[i + 1]]) inc(i, 2) appf(result, "$N$1}", [spaces(indent)]) proc symToYamlAux(n: PSym, marker: var TIntSet, indent: int, maxRecDepth: int): PRope = if n == nil: result = toRope("null") elif ContainsOrIncl(marker, n.id): result = ropef("\"$1 @$2\"", [toRope(n.name.s), toRope( strutils.toHex(cast[TAddress](n), sizeof(n) * 2))]) else: var ast = treeToYamlAux(n.ast, marker, indent + 2, maxRecDepth - 1) result = ropeConstr(indent, [toRope("kind"), makeYamlString($n.kind), toRope("name"), makeYamlString(n.name.s), toRope("typ"), typeToYamlAux(n.typ, marker, indent + 2, maxRecDepth - 1), toRope("info"), lineInfoToStr(n.info), toRope("flags"), flagsToStr(n.flags), toRope("magic"), makeYamlString($n.magic), toRope("ast"), ast, toRope("options"), flagsToStr(n.options), toRope("position"), toRope(n.position)]) proc typeToYamlAux(n: PType, marker: var TIntSet, indent: int, maxRecDepth: int): PRope = if n == nil: result = toRope("null") elif ContainsOrIncl(marker, n.id): result = ropef("\"$1 @$2\"", [toRope($n.kind), toRope( strutils.toHex(cast[TAddress](n), sizeof(n) * 2))]) else: if sonsLen(n) > 0: result = toRope("[") for i in countup(0, sonsLen(n) - 1): if i > 0: app(result, ",") appf(result, "$N$1$2", [spaces(indent + 4), typeToYamlAux(n.sons[i], marker, indent + 4, maxRecDepth - 1)]) appf(result, "$N$1]", [spaces(indent + 2)]) else: result = toRope("null") result = ropeConstr(indent, [toRope("kind"), makeYamlString($n.kind), toRope("sym"), symToYamlAux(n.sym, marker, indent + 2, maxRecDepth - 1), toRope("n"), treeToYamlAux(n.n, marker, indent + 2, maxRecDepth - 1), toRope("flags"), FlagsToStr(n.flags), toRope("callconv"), makeYamlString(CallingConvToStr[n.callConv]), toRope("size"), toRope(n.size), toRope("align"), toRope(n.align), toRope("sons"), result]) proc treeToYamlAux(n: PNode, marker: var TIntSet, indent: int, maxRecDepth: int): PRope = if n == nil: result = toRope("null") else: var istr = spaces(indent + 2) result = ropef("{$N$1\"kind\": $2", [istr, makeYamlString($n.kind)]) if maxRecDepth != 0: appf(result, ",$N$1\"info\": $2", [istr, lineInfoToStr(n.info)]) case n.kind of nkCharLit..nkInt64Lit: appf(result, ",$N$1\"intVal\": $2", [istr, toRope(n.intVal)]) of nkFloatLit, nkFloat32Lit, nkFloat64Lit: appf(result, ",$N$1\"floatVal\": $2", [istr, toRope(n.floatVal.ToStrMaxPrecision)]) of nkStrLit..nkTripleStrLit: appf(result, ",$N$1\"strVal\": $2", [istr, makeYamlString(n.strVal)]) of nkSym: appf(result, ",$N$1\"sym\": $2", [istr, symToYamlAux(n.sym, marker, indent + 2, maxRecDepth)]) of nkIdent: if n.ident != nil: appf(result, ",$N$1\"ident\": $2", [istr, makeYamlString(n.ident.s)]) else: appf(result, ",$N$1\"ident\": null", [istr]) else: if sonsLen(n) > 0: appf(result, ",$N$1\"sons\": [", [istr]) for i in countup(0, sonsLen(n) - 1): if i > 0: app(result, ",") appf(result, "$N$1$2", [spaces(indent + 4), treeToYamlAux(n.sons[i], marker, indent + 4, maxRecDepth - 1)]) appf(result, "$N$1]", [istr]) appf(result, ",$N$1\"typ\": $2", [istr, typeToYamlAux(n.typ, marker, indent + 2, maxRecDepth)]) appf(result, "$N$1}", [spaces(indent)]) proc treeToYaml(n: PNode, indent: int = 0, maxRecDepth: int = - 1): PRope = var marker = InitIntSet() result = treeToYamlAux(n, marker, indent, maxRecDepth) proc typeToYaml(n: PType, indent: int = 0, maxRecDepth: int = - 1): PRope = var marker = InitIntSet() result = typeToYamlAux(n, marker, indent, maxRecDepth) proc symToYaml(n: PSym, indent: int = 0, maxRecDepth: int = - 1): PRope = var marker = InitIntSet() result = symToYamlAux(n, marker, indent, maxRecDepth) proc debugTree(n: PNode, indent: int, maxRecDepth: int): PRope proc debugType(n: PType): PRope = if n == nil: result = toRope("null") else: result = toRope($n.kind) if n.sym != nil: app(result, " ") app(result, n.sym.name.s) if (n.kind != tyString) and (sonsLen(n) > 0): app(result, "(") for i in countup(0, sonsLen(n) - 1): if i > 0: app(result, ", ") if n.sons[i] == nil: app(result, "null") else: app(result, debugType(n.sons[i])) if n.kind == tyObject and n.n != nil: app(result, ", node: ") app(result, debugTree(n.n, 2, 100)) app(result, ")") proc debugTree(n: PNode, indent: int, maxRecDepth: int): PRope = if n == nil: result = toRope("null") else: var istr = spaces(indent + 2) result = ropef("{$N$1\"kind\": $2", [istr, makeYamlString($n.kind)]) if maxRecDepth != 0: case n.kind of nkCharLit..nkInt64Lit: appf(result, ",$N$1\"intVal\": $2", [istr, toRope(n.intVal)]) of nkFloatLit, nkFloat32Lit, nkFloat64Lit: appf(result, ",$N$1\"floatVal\": $2", [istr, toRope(n.floatVal.ToStrMaxPrecision)]) of nkStrLit..nkTripleStrLit: appf(result, ",$N$1\"strVal\": $2", [istr, makeYamlString(n.strVal)]) of nkSym: appf(result, ",$N$1\"sym\": $2_$3", [istr, toRope(n.sym.name.s), toRope(n.sym.id)]) # [istr, symToYaml(n.sym, indent, maxRecDepth), # toRope(n.sym.id)]) of nkIdent: if n.ident != nil: appf(result, ",$N$1\"ident\": $2", [istr, makeYamlString(n.ident.s)]) else: appf(result, ",$N$1\"ident\": null", [istr]) else: if sonsLen(n) > 0: appf(result, ",$N$1\"sons\": [", [istr]) for i in countup(0, sonsLen(n) - 1): if i > 0: app(result, ",") appf(result, "$N$1$2", [spaces(indent + 4), debugTree(n.sons[i], indent + 4, maxRecDepth - 1)]) appf(result, "$N$1]", [istr]) appf(result, ",$N$1\"info\": $2", [istr, lineInfoToStr(n.info)]) appf(result, "$N$1}", [spaces(indent)]) proc debug(n: PSym) = #writeln(stdout, ropeToStr(symToYaml(n, 0, 1))) writeln(stdout, ropeToStr(ropef("$1_$2: $3, $4", [ toRope(n.name.s), toRope(n.id), flagsToStr(n.flags), flagsToStr(n.loc.flags)]))) proc debug(n: PType) = writeln(stdout, ropeToStr(debugType(n))) proc debug(n: PNode) = writeln(stdout, ropeToStr(debugTree(n, 0, 100))) const EmptySeq = @[] proc nextTry(h, maxHash: THash): THash = result = ((5 * h) + 1) and maxHash # For any initial h in range(maxHash), repeating that maxHash times # generates each int in range(maxHash) exactly once (see any text on # random-number generation for proof). proc objectSetContains(t: TObjectSet, obj: PObject): bool = # returns true whether n is in t var h: THash = hashNode(obj) and high(t.data) # start with real hash value while t.data[h] != nil: if (t.data[h] == obj): return true h = nextTry(h, high(t.data)) result = false proc objectSetRawInsert(data: var TObjectSeq, obj: PObject) = var h: THash = HashNode(obj) and high(data) while data[h] != nil: assert(data[h] != obj) h = nextTry(h, high(data)) assert(data[h] == nil) data[h] = obj proc objectSetEnlarge(t: var TObjectSet) = var n: TObjectSeq newSeq(n, len(t.data) * growthFactor) for i in countup(0, high(t.data)): if t.data[i] != nil: objectSetRawInsert(n, t.data[i]) swap(t.data, n) proc objectSetIncl(t: var TObjectSet, obj: PObject) = if mustRehash(len(t.data), t.counter): objectSetEnlarge(t) objectSetRawInsert(t.data, obj) inc(t.counter) proc objectSetContainsOrIncl(t: var TObjectSet, obj: PObject): bool = # returns true if obj is already in the string table: var h: THash = HashNode(obj) and high(t.data) while true: var it = t.data[h] if it == nil: break if it == obj: return true # found it h = nextTry(h, high(t.data)) if mustRehash(len(t.data), t.counter): objectSetEnlarge(t) objectSetRawInsert(t.data, obj) else: assert(t.data[h] == nil) t.data[h] = obj inc(t.counter) result = false proc TableRawGet(t: TTable, key: PObject): int = var h: THash = hashNode(key) and high(t.data) # start with real hash value while t.data[h].key != nil: if t.data[h].key == key: return h h = nextTry(h, high(t.data)) result = -1 proc TableSearch(t: TTable, key, closure: PObject, comparator: TCmpProc): PObject = var h: THash = hashNode(key) and high(t.data) # start with real hash value while t.data[h].key != nil: if t.data[h].key == key: if comparator(t.data[h].val, closure): # BUGFIX 1 return t.data[h].val h = nextTry(h, high(t.data)) result = nil proc TableGet(t: TTable, key: PObject): PObject = var index = TableRawGet(t, key) if index >= 0: result = t.data[index].val else: result = nil proc TableRawInsert(data: var TPairSeq, key, val: PObject) = var h: THash = HashNode(key) and high(data) while data[h].key != nil: assert(data[h].key != key) h = nextTry(h, high(data)) assert(data[h].key == nil) data[h].key = key data[h].val = val proc TableEnlarge(t: var TTable) = var n: TPairSeq newSeq(n, len(t.data) * growthFactor) for i in countup(0, high(t.data)): if t.data[i].key != nil: TableRawInsert(n, t.data[i].key, t.data[i].val) swap(t.data, n) proc TablePut(t: var TTable, key, val: PObject) = var index = TableRawGet(t, key) if index >= 0: t.data[index].val = val else: if mustRehash(len(t.data), t.counter): TableEnlarge(t) TableRawInsert(t.data, key, val) inc(t.counter) proc StrTableContains(t: TStrTable, n: PSym): bool = var h: THash = n.name.h and high(t.data) # start with real hash value while t.data[h] != nil: if (t.data[h] == n): return true h = nextTry(h, high(t.data)) result = false proc StrTableRawInsert(data: var TSymSeq, n: PSym) = var h: THash = n.name.h and high(data) while data[h] != nil: if data[h] == n: InternalError(n.info, "StrTableRawInsert: " & n.name.s) return h = nextTry(h, high(data)) assert(data[h] == nil) data[h] = n proc SymTabReplaceRaw(data: var TSymSeq, prevSym: PSym, newSym: PSym) = assert prevSym.name.h == newSym.name.h var h: THash = prevSym.name.h and high(data) while data[h] != nil: if data[h] == prevSym: data[h] = newSym return h = nextTry(h, high(data)) assert false proc SymTabReplace*(t: var TStrTable, prevSym: PSym, newSym: PSym) = SymTabReplaceRaw(t.data, prevSym, newSym) proc StrTableEnlarge(t: var TStrTable) = var n: TSymSeq newSeq(n, len(t.data) * growthFactor) for i in countup(0, high(t.data)): if t.data[i] != nil: StrTableRawInsert(n, t.data[i]) swap(t.data, n) proc StrTableAdd(t: var TStrTable, n: PSym) = if mustRehash(len(t.data), t.counter): StrTableEnlarge(t) StrTableRawInsert(t.data, n) inc(t.counter) proc StrTableIncl*(t: var TStrTable, n: PSym): bool = # returns true if n is already in the string table: # It is essential that `n` is written nevertheless! # This way the newest redefinition is picked by the semantic analyses! assert n.name != nil var h: THash = n.name.h and high(t.data) while true: var it = t.data[h] if it == nil: break if it.name.id == n.name.id: t.data[h] = n # overwrite it with newer definition! return true # found it h = nextTry(h, high(t.data)) if mustRehash(len(t.data), t.counter): StrTableEnlarge(t) StrTableRawInsert(t.data, n) else: assert(t.data[h] == nil) t.data[h] = n inc(t.counter) result = false proc StrTableGet(t: TStrTable, name: PIdent): PSym = var h: THash = name.h and high(t.data) while true: result = t.data[h] if result == nil: break if result.name.id == name.id: break h = nextTry(h, high(t.data)) proc InitIdentIter(ti: var TIdentIter, tab: TStrTable, s: PIdent): PSym = ti.h = s.h ti.name = s if tab.Counter == 0: result = nil else: result = NextIdentIter(ti, tab) proc NextIdentIter(ti: var TIdentIter, tab: TStrTable): PSym = var h, start: THash h = ti.h and high(tab.data) start = h result = tab.data[h] while result != nil: if result.Name.id == ti.name.id: break h = nextTry(h, high(tab.data)) if h == start: result = nil break result = tab.data[h] ti.h = nextTry(h, high(tab.data)) proc NextIdentExcluding*(ti: var TIdentIter, tab: TStrTable, excluding: TIntSet): PSym = var h: THash = ti.h and high(tab.data) var start = h result = tab.data[h] while result != nil: if result.Name.id == ti.name.id and not Contains(excluding, result.id): break h = nextTry(h, high(tab.data)) if h == start: result = nil break result = tab.data[h] ti.h = nextTry(h, high(tab.data)) if result != nil and Contains(excluding, result.id): result = nil proc FirstIdentExcluding*(ti: var TIdentIter, tab: TStrTable, s: PIdent, excluding: TIntSet): PSym = ti.h = s.h ti.name = s if tab.Counter == 0: result = nil else: result = NextIdentExcluding(ti, tab, excluding) proc InitTabIter(ti: var TTabIter, tab: TStrTable): PSym = ti.h = 0 # we start by zero ... if tab.counter == 0: result = nil # FIX 1: removed endless loop else: result = NextIter(ti, tab) proc NextIter(ti: var TTabIter, tab: TStrTable): PSym = result = nil while (ti.h <= high(tab.data)): result = tab.data[ti.h] Inc(ti.h) # ... and increment by one always if result != nil: break proc InitSymTab(tab: var TSymTab) = tab.tos = 0 tab.stack = EmptySeq proc DeinitSymTab(tab: var TSymTab) = tab.stack = nil proc SymTabLocalGet(tab: TSymTab, s: PIdent): PSym = result = StrTableGet(tab.stack[tab.tos - 1], s) proc SymTabGet(tab: TSymTab, s: PIdent): PSym = for i in countdown(tab.tos - 1, 0): result = StrTableGet(tab.stack[i], s) if result != nil: return result = nil proc SymTabGet*(tab: TSymTab, s: PIdent, filter: TSymKinds): PSym = for i in countdown(tab.tos - 1, 0): result = StrTableGet(tab.stack[i], s) if result != nil and result.kind in filter: return result = nil proc SymTabAddAt(tab: var TSymTab, e: PSym, at: Natural) = StrTableAdd(tab.stack[at], e) proc SymTabAdd(tab: var TSymTab, e: PSym) = StrTableAdd(tab.stack[tab.tos - 1], e) proc SymTabAddUniqueAt(tab: var TSymTab, e: PSym, at: Natural): TResult = if StrTableIncl(tab.stack[at], e): result = Failure else: result = Success proc SymTabAddUnique(tab: var TSymTab, e: PSym): TResult = result = SymTabAddUniqueAt(tab, e, tab.tos - 1) proc OpenScope(tab: var TSymTab) = if tab.tos >= len(tab.stack): setlen(tab.stack, tab.tos + 1) initStrTable(tab.stack[tab.tos]) Inc(tab.tos) proc RawCloseScope(tab: var TSymTab) = Dec(tab.tos) iterator items*(tab: TStrTable): PSym = var it: TTabIter var s = InitTabIter(it, tab) while s != nil: yield s s = NextIter(it, tab) iterator items*(tab: TSymTab): PSym = for i in countdown(tab.tos-1, 0): for it in items(tab.stack[i]): yield it proc hasEmptySlot(data: TIdPairSeq): bool = for h in countup(0, high(data)): if data[h].key == nil: return true result = false proc IdTableRawGet(t: TIdTable, key: int): int = var h: THash h = key and high(t.data) # start with real hash value while t.data[h].key != nil: if (t.data[h].key.id == key): return h h = nextTry(h, high(t.data)) result = - 1 proc IdTableHasObjectAsKey(t: TIdTable, key: PIdObj): bool = var index = IdTableRawGet(t, key.id) if index >= 0: result = t.data[index].key == key else: result = false proc IdTableGet(t: TIdTable, key: PIdObj): PObject = var index = IdTableRawGet(t, key.id) if index >= 0: result = t.data[index].val else: result = nil proc IdTableGet(t: TIdTable, key: int): PObject = var index = IdTableRawGet(t, key) if index >= 0: result = t.data[index].val else: result = nil iterator pairs*(t: TIdTable): tuple[key: int, value: PObject] = for i in 0..high(t.data): if t.data[i].key != nil: yield (t.data[i].key.id, t.data[i].val) proc IdTableRawInsert(data: var TIdPairSeq, key: PIdObj, val: PObject) = var h: THash h = key.id and high(data) while data[h].key != nil: assert(data[h].key.id != key.id) h = nextTry(h, high(data)) assert(data[h].key == nil) data[h].key = key data[h].val = val proc IdTablePut(t: var TIdTable, key: PIdObj, val: PObject) = var index: int n: TIdPairSeq index = IdTableRawGet(t, key.id) if index >= 0: assert(t.data[index].key != nil) t.data[index].val = val else: if mustRehash(len(t.data), t.counter): newSeq(n, len(t.data) * growthFactor) for i in countup(0, high(t.data)): if t.data[i].key != nil: IdTableRawInsert(n, t.data[i].key, t.data[i].val) assert(hasEmptySlot(n)) swap(t.data, n) IdTableRawInsert(t.data, key, val) inc(t.counter) iterator IdTablePairs*(t: TIdTable): tuple[key: PIdObj, val: PObject] = for i in 0 .. high(t.data): if not isNil(t.data[i].key): yield (t.data[i].key, t.data[i].val) proc writeIdNodeTable(t: TIdNodeTable) = nil proc IdNodeTableRawGet(t: TIdNodeTable, key: PIdObj): int = var h: THash h = key.id and high(t.data) # start with real hash value while t.data[h].key != nil: if t.data[h].key.id == key.id: return h h = nextTry(h, high(t.data)) result = - 1 proc IdNodeTableGet(t: TIdNodeTable, key: PIdObj): PNode = var index: int index = IdNodeTableRawGet(t, key) if index >= 0: result = t.data[index].val else: result = nil proc IdNodeTableGetLazy*(t: TIdNodeTable, key: PIdObj): PNode = if not isNil(t.data): result = IdNodeTableGet(t, key) proc IdNodeTableRawInsert(data: var TIdNodePairSeq, key: PIdObj, val: PNode) = var h: THash h = key.id and high(data) while data[h].key != nil: assert(data[h].key.id != key.id) h = nextTry(h, high(data)) assert(data[h].key == nil) data[h].key = key data[h].val = val proc IdNodeTablePut(t: var TIdNodeTable, key: PIdObj, val: PNode) = var index = IdNodeTableRawGet(t, key) if index >= 0: assert(t.data[index].key != nil) t.data[index].val = val else: if mustRehash(len(t.data), t.counter): var n: TIdNodePairSeq newSeq(n, len(t.data) * growthFactor) for i in countup(0, high(t.data)): if t.data[i].key != nil: IdNodeTableRawInsert(n, t.data[i].key, t.data[i].val) swap(t.data, n) IdNodeTableRawInsert(t.data, key, val) inc(t.counter) proc IdNodeTablePutLazy*(t: var TIdNodeTable, key: PIdObj, val: PNode) = if isNil(t.data): initIdNodeTable(t) IdNodeTablePut(t, key, val) iterator pairs*(t: TIdNodeTable): tuple[key: PIdObj, val: PNode] = for i in 0 .. high(t.data): if not isNil(t.data[i].key): yield (t.data[i].key, t.data[i].val) proc initIITable(x: var TIITable) = x.counter = 0 newSeq(x.data, startSize) for i in countup(0, startSize - 1): x.data[i].key = InvalidKey proc IITableRawGet(t: TIITable, key: int): int = var h: THash h = key and high(t.data) # start with real hash value while t.data[h].key != InvalidKey: if (t.data[h].key == key): return h h = nextTry(h, high(t.data)) result = - 1 proc IITableGet(t: TIITable, key: int): int = var index = IITableRawGet(t, key) if index >= 0: result = t.data[index].val else: result = InvalidKey proc IITableRawInsert(data: var TIIPairSeq, key, val: int) = var h: THash h = key and high(data) while data[h].key != InvalidKey: assert(data[h].key != key) h = nextTry(h, high(data)) assert(data[h].key == InvalidKey) data[h].key = key data[h].val = val proc IITablePut(t: var TIITable, key, val: int) = var index = IITableRawGet(t, key) if index >= 0: assert(t.data[index].key != InvalidKey) t.data[index].val = val else: if mustRehash(len(t.data), t.counter): var n: TIIPairSeq newSeq(n, len(t.data) * growthFactor) for i in countup(0, high(n)): n[i].key = InvalidKey for i in countup(0, high(t.data)): if t.data[i].key != InvalidKey: IITableRawInsert(n, t.data[i].key, t.data[i].val) swap(t.data, n) IITableRawInsert(t.data, key, val) inc(t.counter)