1 ###############################################################################
3 # Class: NaturalDocs::Languages::Tcl
5 ###############################################################################
7 # A subclass to handle the language variations of Tcl.
9 ###############################################################################
11 # This file is part of Natural Docs, which is Copyright © 2003-2010 Greg Valure
12 # Natural Docs is licensed under version 3 of the GNU Affero General Public License (AGPL)
13 # Refer to License.txt for the complete details
18 package NaturalDocs::Languages::Tcl;
20 use base 'NaturalDocs::Languages::Simple';
24 # bool: pastFirstBrace
26 # Whether we've past the first brace in a function prototype or not.
34 # This is just overridden to reset <pastFirstBrace>.
38 my ($self, @params) = @_;
42 return $self->SUPER::OnCode(@params);
47 # Function: OnPrototypeEnd
49 # Tcl's function syntax is shown below.
51 # > proc [name] { [params] } { [code] }
53 # The opening brace is one of the prototype enders. We need to allow the first opening brace because it contains the
56 # Also, the parameters may have braces within them. I've seen one that used { seconds 20 } as a parameter.
60 # type - The <TopicType> of the prototype.
61 # prototypeRef - A reference to the prototype so far, minus the ender in dispute.
62 # ender - The ender symbol.
66 # ENDER_ACCEPT - The ender is accepted and the prototype is finished.
67 # ENDER_IGNORE - The ender is rejected and parsing should continue. Note that the prototype will be rejected as a whole
68 # if all enders are ignored before reaching the end of the code.
69 # ENDER_ACCEPT_AND_CONTINUE - The ender is accepted so the prototype may stand as is. However, the prototype might
70 # also continue on so continue parsing. If there is no accepted ender between here and
71 # the end of the code this version will be accepted instead.
72 # ENDER_REVERT_TO_ACCEPTED - The expedition from ENDER_ACCEPT_AND_CONTINUE failed. Use the last accepted
73 # version and end parsing.
75 sub OnPrototypeEnd #(type, prototypeRef, ender)
77 my ($self, $type, $prototypeRef, $ender) = @_;
79 if ($type eq ::TOPIC_FUNCTION() && $ender eq '{' && !$pastFirstBrace)
82 return ::ENDER_IGNORE();
85 { return ::ENDER_ACCEPT(); };
90 # Function: ParsePrototype
92 # Parses the prototype and returns it as a <NaturalDocs::Languages::Prototype> object.
96 # type - The <TopicType>.
97 # prototype - The text prototype.
101 # A <NaturalDocs::Languages::Prototype> object.
103 sub ParsePrototype #(type, prototype)
105 my ($self, $type, $prototype) = @_;
107 if ($type ne ::TOPIC_FUNCTION())
109 my $object = NaturalDocs::Languages::Prototype->New($prototype);
114 # Parse the parameters out of the prototype.
116 my @tokens = $prototype =~ /([^\{\}\ ]+|.)/g;
123 my ($beforeParameters, $afterParameters, $finishedParameters);
125 foreach my $token (@tokens)
127 if ($finishedParameters)
128 { $afterParameters .= $token; }
130 elsif ($token eq '{')
132 if ($braceLevel == 0)
133 { $beforeParameters .= $token; }
135 else # braceLevel > 0
136 { $parameter .= $token; };
141 elsif ($token eq '}')
143 if ($braceLevel == 1)
145 if ($parameter && $parameter ne ' ')
146 { push @parameterLines, $parameter; };
148 $finishedParameters = 1;
149 $afterParameters .= $token;
153 elsif ($braceLevel > 1)
155 $parameter .= $token;
160 elsif ($token eq ' ')
162 if ($braceLevel == 1)
165 { push @parameterLines, $parameter; };
169 elsif ($braceLevel > 1)
171 $parameter .= $token;
175 $beforeParameters .= $token;
182 { $parameter .= $token; }
184 { $beforeParameters .= $token; };
188 foreach my $part (\$beforeParameters, \$afterParameters)
194 my $prototypeObject = NaturalDocs::Languages::Prototype->New($beforeParameters, $afterParameters);
197 # Parse the actual parameters.
199 foreach my $parameterLine (@parameterLines)
201 $prototypeObject->AddParameter( $self->ParseParameterLine($parameterLine) );
204 return $prototypeObject;
209 # Function: ParseParameterLine
211 # Parses a prototype parameter line and returns it as a <NaturalDocs::Languages::Prototype::Parameter> object.
213 sub ParseParameterLine #(line)
215 my ($self, $line) = @_;
216 return NaturalDocs::Languages::Prototype::Parameter->New(undef, undef, $line, undef, undef, undef);