For complete information evaluate "Object tgenCopyright."
=================================================
This abstract class provides the framework for both destructive and non-destructive tree traversals in which references to locally global objects are available without being explicitly passed as arguments.
Concrete subclasses must implement methods for traversing
childrenDo:
"Evaluate the argument block with each of my children."
updateChildrenUsing:
"Replace my children with the result of evaluating the argument block with the corresponding child."'!
For complete information evaluate "Object tgenCopyright."
=================================================
This abstract class provides the framework for both destructive and non-destructive tree traversals in which references to locally global objects are available without being explicitly passed as arguments.
Concrete subclasses must implement methods for traversing
childrenDo:
"Evaluate the argument block with each of my children."
updateChildrenUsing:
"Replace my children with the result of evaluating the argument block with the corresponding child."'!
!TreeNode methodsFor: 'traversing'!
childrenDo: aBlock
"Evaluate aBlock for each of my children.
This message should be reimplemented by my subclasses."
^self "default"! !
!TreeNode methodsFor: 'traversing'!
preorderDo: preBlock updateUsing: postBlock
"Perform a traversal on myself and my children. The preBlock is
evaluated when first entering a node. My children are replaced
with the results of the traversal. Thus, this message can be used
to generate objects or alter my structure, whereas postorderDo:
can only be used to examine my structure. This message may be
For complete information evaluate "Object tgenCopyright."
=================================================
I am an abstract class that provides the framework for creating objects from textual representations using a recursive descent parse.
This class is what used to be called ''NewCompiler'' in old TS implementations. It has not been rewritten to reflect its new place in the compiler framework in order to maintain compatibility with the old TS subclasses. When they are rewritten (when the Tektronix implementation is abandoned) this class should be also.
Instance Variables:
here <Object> the current token
hereType <Symbol> the "type" of the current token
hereMark <Integer> position in source stream (mark) where this token began
prevToken* <Integer> size in chars of the previous token parsed
prevMark <Integer> mark of previous token
class <Class> provides a context for the text being parsed
encoder <Encoder> which uses tables to decode tokens
parseNode <ParseNode> intermediate result of current parse (for use by subclasses)
lastTempMark <Integer> mark of last temp;
points to vert bar, or last char of pattern if no temps declared
correctionDelta <Integer> offset of corrected code relative to source stream
owing to interactive corrections so far.
* inherited from AbstractParser, but with new semantics.'!
For complete information evaluate "Object tgenCopyright."
=================================================
I am an abstract class that provides the framework for creating objects from textual representations using a recursive descent parse.
This class is what used to be called ''NewCompiler'' in old TS implementations. It has not been rewritten to reflect its new place in the compiler framework in order to maintain compatibility with the old TS subclasses. When they are rewritten (when the Tektronix implementation is abandoned) this class should be also.
Instance Variables:
here <Object> the current token
hereType <Symbol> the "type" of the current token
hereMark <Integer> position in source stream (mark) where this token began
prevToken* <Integer> size in chars of the previous token parsed
prevMark <Integer> mark of previous token
class <Class> provides a context for the text being parsed
encoder <Encoder> which uses tables to decode tokens
parseNode <ParseNode> intermediate result of current parse (for use by subclasses)
lastTempMark <Integer> mark of last temp;
points to vert bar, or last char of pattern if no temps declared
correctionDelta <Integer> offset of corrected code relative to source stream
owing to interactive corrections so far.
* inherited from AbstractParser, but with new semantics.'!
For complete information evaluate "Object tgenCopyright."
=================================================
I am an abstract class of scanner that scans a source string and breaks it up into tokens using a minimal deterministic finite-state automata (FSA). Each token is also given a type by its associated final state in the FSA. Specific FSAs are stored in class instance variables of my concrete subclasses.
Instance Variables:
fsa <FSAState> - a local reference to the token recognizer, in minimal deterministic form, for this class of scanner.
For complete information evaluate "Object tgenCopyright."
=================================================
I am an abstract class of scanner that scans a source string and breaks it up into tokens using a minimal deterministic finite-state automata (FSA). Each token is also given a type by its associated final state in the FSA. Specific FSAs are stored in class instance variables of my concrete subclasses.
Instance Variables:
fsa <FSAState> - a local reference to the token recognizer, in minimal deterministic form, for this class of scanner.
For complete information evaluate "Object tgenCopyright."
=================================================
I am an abstract class of scanner that scans a source string and breaks it up into tokens using a character type table and hand-coded scanner methods. Specific type tables are stored in class instance variables of my concrete subclasses.
Instance Variables:
charTypeTable <Array of: Symbol> - a local reference to the type table for this class of scanner; the ascii value of each character is mapped to a symbol token type.
For complete information evaluate "Object tgenCopyright."
=================================================
I am an abstract class of scanner that scans a source string and breaks it up into tokens using a character type table and hand-coded scanner methods. Specific type tables are stored in class instance variables of my concrete subclasses.
Instance Variables:
charTypeTable <Array of: Symbol> - a local reference to the type table for this class of scanner; the ascii value of each character is mapped to a symbol token type.
'!
!HandCodedScanner methodsFor: 'state accessing'!
charTypeTable
^charTypeTable! !
!HandCodedScanner methodsFor: 'state accessing'!
charTypeTable: argument
charTypeTable := argument! !
!HandCodedScanner methodsFor: 'initialization'!
init
super init.
self charTypeTable: self myTypeTable! !
!HandCodedScanner methodsFor: 'accessing'!
endOfInputToken
"Answer a token representing the end of the input."
^nil! !
!HandCodedScanner methodsFor: 'accessing'!
endOfInputTokenType
"Answer the token type representing the end of the input."
^#doIt! !
!HandCodedScanner methodsFor: 'accessing'!
myTypeTable
^self class charTypeTable! !
!HandCodedScanner methodsFor: 'testing'!
atStartOfComplexToken
"Answer true if the first character of the tokenType is an $x and false otherwise."
^(self tokenType at: 1)
= $x! !
!HandCodedScanner methodsFor: 'scanning'!
scanToken
"Scan the next token and compute its token type. This may be
overridden in subclasses for efficiency and customization."
For complete information evaluate "Object tgenCopyright."
=================================================
It is often helpful to create a node that has a arbitrary (but flat) collection of nodes as a child. My instances provide containers for these "collection children". In other words, I am a collection that acts like a single parse tree node.'!
For complete information evaluate "Object tgenCopyright."
=================================================
It is often helpful to create a node that has a arbitrary (but flat) collection of nodes as a child. My instances provide containers for these "collection children". In other words, I am a collection that acts like a single parse tree node.'!
For complete information evaluate "Object tgenCopyright."
=================================================
This is an abstract class that provides a framework for building parse trees during parsing. Parse trees are built in a bottom-up fashion during parsing by processing key productions, and with the help of a stack. In general, a key production has the form:
A -> N1 N2 ... Nk => symbol
where A and the Ni are nonterminals (terminals may be interspersed freely in the right-hand side) and symbol is the production directive (or translation symbol). Since trees are built bottom-up, the information flow in a production is from the right-hand side to the left-hand side. When a production is ready to be processed, the top of the stack contains objects (parse trees) associated with the right-hand-side nonterminals of the production. Processing a production involves replacing these objects with a single object representing (associated with) the left-hand-side nonterminal. This can be thought of as computing a value for A as a function of the values of the Ni''s, i.e. value(A) = fcn(value(N1), value(N2), ..., value(Nk)). Default functions are defined in my concrete subclasses but users may define their own production processing functions by creating a new subclass and implementing appropriate messages. This enables users to have direct control over exactly how parse trees are built.
Instance Variables:
stack <Stack> - holds intermediate node values during production processing.'!
For complete information evaluate "Object tgenCopyright."
=================================================
This is an abstract class that provides a framework for building parse trees during parsing. Parse trees are built in a bottom-up fashion during parsing by processing key productions, and with the help of a stack. In general, a key production has the form:
A -> N1 N2 ... Nk => symbol
where A and the Ni are nonterminals (terminals may be interspersed freely in the right-hand side) and symbol is the production directive (or translation symbol). Since trees are built bottom-up, the information flow in a production is from the right-hand side to the left-hand side. When a production is ready to be processed, the top of the stack contains objects (parse trees) associated with the right-hand-side nonterminals of the production. Processing a production involves replacing these objects with a single object representing (associated with) the left-hand-side nonterminal. This can be thought of as computing a value for A as a function of the values of the Ni''s, i.e. value(A) = fcn(value(N1), value(N2), ..., value(Nk)). Default functions are defined in my concrete subclasses but users may define their own production processing functions by creating a new subclass and implementing appropriate messages. This enables users to have direct control over exactly how parse trees are built.
Instance Variables:
stack <Stack> - holds intermediate node values during production processing.'!
!ParseTreeBuilder methodsFor: 'initialization'!
init
self stack: Stack new! !
!ParseTreeBuilder methodsFor: 'state accessing'!
stack
^stack! !
!ParseTreeBuilder methodsFor: 'state accessing'!
stack: argument
stack := argument! !
!ParseTreeBuilder methodsFor: 'accessing'!
popStack
^self stack pop! !
!ParseTreeBuilder methodsFor: 'accessing'!
pushStack: anObject
^self stack push: anObject! !
!ParseTreeBuilder methodsFor: 'accessing'!
result
"Answer the root of the tree build by this tree builder."
For complete information evaluate "Object tgenCopyright."
=================================================
I build parse trees by creating specific objects for each kind of node as indicated by the parser directives in grammar productions. Parser directives currently fall into one of three groups: node (class) names, special directives, and arbitrary message selectors. For a node name, a new instance of the specified node is created and given the values associated with the right-hand side nonterminals, if any, as its children. The special directive ''nil'' simply returns nil. The directive liftRightChild adds any nodes preceeding the right-most node as children to the right-most node, and returns the right-most node. The directive liftLeftChild works in an analogous fashion. Arbitrary message selectors must take the same number of arguments as there are right-hand-side nodes and are invoked as a builder message, thus allowing users to define their own tree-building messages.
Productions of the form ''A -> <tc> => symbol'' are treated specially. The symbol can be either a node name or a one-argument message selector. If it is a node name then create a new instance of that node with the specified attribute value. If it is a message selector then invoke the corresponding operation on the builder with the specified value.
Instance Variables:
shamMode <Boolean> - If true DerivationTreeNode-based ASTs are built, otherwise specific ParseTreeNode-based ASTs are built.'!
For complete information evaluate "Object tgenCopyright."
=================================================
I build parse trees by creating specific objects for each kind of node as indicated by the parser directives in grammar productions. Parser directives currently fall into one of three groups: node (class) names, special directives, and arbitrary message selectors. For a node name, a new instance of the specified node is created and given the values associated with the right-hand side nonterminals, if any, as its children. The special directive ''nil'' simply returns nil. The directive liftRightChild adds any nodes preceeding the right-most node as children to the right-most node, and returns the right-most node. The directive liftLeftChild works in an analogous fashion. Arbitrary message selectors must take the same number of arguments as there are right-hand-side nodes and are invoked as a builder message, thus allowing users to define their own tree-building messages.
Productions of the form ''A -> <tc> => symbol'' are treated specially. The symbol can be either a node name or a one-argument message selector. If it is a node name then create a new instance of that node with the specified attribute value. If it is a message selector then invoke the corresponding operation on the builder with the specified value.
Instance Variables:
shamMode <Boolean> - If true DerivationTreeNode-based ASTs are built, otherwise specific ParseTreeNode-based ASTs are built.'!
For complete information evaluate "Object tgenCopyright."
=================================================
This concrete class is used for building derivation trees for a parse. It uses homogeneous DerivationTreeNodes for all nodes and a specialized production processor.'!
For complete information evaluate "Object tgenCopyright."
=================================================
This concrete class is used for building derivation trees for a parse. It uses homogeneous DerivationTreeNodes for all nodes and a specialized production processor.'!
For complete information evaluate "Object tgenCopyright."
=================================================
I am an abstract class that provides the framework for parse tree nodes, basically just a reminder that the following messages may need to be implemented by concrete subclasses:
For complete information evaluate "Object tgenCopyright."
=================================================
I am an abstract class that provides the framework for parse tree nodes, basically just a reminder that the following messages may need to be implemented by concrete subclasses:
For complete information evaluate "Object tgenCopyright."
=================================================
I represent an arbitrary node in a derivation or abstract tree. (It would be nice to expand this concept so that heterogeneous parse trees could be built.)
Instance Variables:
symbol <String> - node attribute.
children <OrderedCollection of: DerivationTreeNode>'!
For complete information evaluate "Object tgenCopyright."
=================================================
I represent an arbitrary node in a derivation or abstract tree. (It would be nice to expand this concept so that heterogeneous parse trees could be built.)
Instance Variables:
symbol <String> - node attribute.
children <OrderedCollection of: DerivationTreeNode>'!
For complete information evaluate "Object tgenCopyright."
=================================================
I represent one production of a context-free grammar. I am responsible for some parts of the first/follow set computation algorithm and for converting myself between various related representations (e.g. LR(0) items).
For complete information evaluate "Object tgenCopyright."
=================================================
I represent one production of a context-free grammar. I am responsible for some parts of the first/follow set computation algorithm and for converting myself between various related representations (e.g. LR(0) items).
For complete information evaluate "Object tgenCopyright."
=================================================
I add a translation attribute to context-free grammar productions so that I can be used to build simple transduction grammars (or syntax-directed translation scheme). Transduction grammars are used to build abstract syntax trees rather than derivation trees during parsing. For more information, refer to Chapter 7. ("Syntax-Directed Translation") in {\em Compiler Construction: Theory and Practice} by Barrett, Bates, Gustafson, and Couch.
Instance Variables:
translationSymbol <String> - used as basis for translation node when parsing.'!
For complete information evaluate "Object tgenCopyright."
=================================================
I add a translation attribute to context-free grammar productions so that I can be used to build simple transduction grammars (or syntax-directed translation scheme). Transduction grammars are used to build abstract syntax trees rather than derivation trees during parsing. For more information, refer to Chapter 7. ("Syntax-Directed Translation") in {\em Compiler Construction: Theory and Practice} by Barrett, Bates, Gustafson, and Couch.
Instance Variables:
translationSymbol <String> - used as basis for translation node when parsing.'!
!TransductionGrammarProduction methodsFor: 'parse tree building'!
computeResultNodeFor: builder withArgNodes: nodes
"Three kinds of translation symbols are currently supported: node names, special
directives, and arbitrary message selectors. For a node name, a new instance of
the specified node is created and given nodes, if any, as its children. The special
directive 'nil' simply returns nil. The directive liftRightChild adds any nodes
preceeding the right-most node as children to the right-most node, and returns
the right-most node. The directive liftLeftChild works in an analogous fashion.
Arbitrary message selectors must take the number of arguments in nodes and
are invoked as a builder message, thus allowing users to define their own
tree-building messages."
| symbol node |
symbol := self translationSymbol asSymbol.
symbol first isUppercase ifTrue: [^nodes isEmpty
ifTrue: [builder makeNewNode: symbol]
ifFalse: [builder makeNewNode: symbol withChildren: nodes]].
symbol = self epsilonSymbol ifTrue: [^builder answerNil].
symbol = self rightLiftSymbol
ifTrue:
[nodes size < 2 ifTrue: [self error: 'Only use liftRightChild when there are at least two right-hand-side nonterminals.'].
"special case for building lists ending with epsilon"
(nodes size = 2 and: [nodes last isNil])
ifTrue: [^builder answerArgument: nodes first].
node := nodes removeLast.
^builder addChildrenFirst: nodes to: node].
symbol = self leftLiftSymbol
ifTrue:
[nodes size < 2 ifTrue: [self error: 'Only use liftLeftChild when there are at least two right-hand-side nonterminals.'].
"special case for building lists beginning with epsilon"
(nodes size = 2 and: [nodes first isNil])
ifTrue: [^builder answerArgument: nodes last].
node := nodes removeFirst.
^builder addChildrenLast: nodes to: node].
symbol numArgs = nodes size ifFalse: [self error: 'Translation message selectors must have the same number of arguments as right-hand-side nonterminals.'].
nodes isEmpty ifTrue: [^builder perform: symbol].
"It may be more efficient to check the number of arguments and use
perform:with:, etc., but probably not."
^builder perform: symbol withArguments: nodes asArray! !
!TransductionGrammarProduction methodsFor: 'parse tree building'!
computeResultNodeFor: builder withTokenClassValue: value
"I am assumed to be a production of the form 'A -> <tc> => symbol'.
The symbol can be either a node name or a one-argument message selector.
If it is a node name then create a new instance of that node with the specified
attribute value. If it is a message selector then invoke the corresponding
operation on the builder with the specified value."
| symbol |
symbol := self translationSymbol asSymbol.
symbol first isUppercase
ifTrue: [^builder makeNewNode: symbol withAttribute: value]
ifFalse: [symbol numArgs = 1
ifTrue: [^builder perform: symbol with: value]
ifFalse: [self error: 'Expected either a node name or a one argument
For complete information evaluate "Object tgenCopyright."
=================================================
I represent a node in an LR parser characteristic finite state machine.
Instance Variables:
edgeLabelMap <Dictionary from: symbols to: successors> - overridden from EdgeLabeledDigraphNode for efficiency since only deterministic FSAs are constructed.
reduceMap <SetDictionary from: symbols to: productions>'!
For complete information evaluate "Object tgenCopyright."
=================================================
I represent a node in an LR parser characteristic finite state machine.
Instance Variables:
edgeLabelMap <Dictionary from: symbols to: successors> - overridden from EdgeLabeledDigraphNode for efficiency since only deterministic FSAs are constructed.
reduceMap <SetDictionary from: symbols to: productions>'!
!LRParserState methodsFor: 'initialization'!
init
super init.
self edgeLabelMap: Dictionary new. "overrides use of SetDictionary in superclass"
self reduceMap: SetDictionary new! !
!LRParserState methodsFor: 'state accessing'!
reduceMap
^reduceMap! !
!LRParserState methodsFor: 'state accessing'!
reduceMap: argument
reduceMap := argument! !
!LRParserState methodsFor: 'exception handling'!
standardErrorString
^'unexpected token encountered: '! !
!LRParserState methodsFor: 'printing'!
printOn: aStream
super printOn: aStream.
aStream cr.
self reduceMap printOn: aStream! !
!LRParserState methodsFor: 'lalr analysis'!
appendHashTo: sym
"Answer a new nonterminal or terminal with my hash value appended."
For complete information evaluate "Object tgenCopyright."
=================================================
I implement a two dimensional LL(1) parser table with rows indexed by nonterminals, columns indexed by terminals, and with production table entries. At the top level I''m a Dictionary from nonterminals to rows; each row is a SetDictionary from terminals to productions. In deterministic tables (tables without multiple entries) the SetDictionaries can be (and are) converted into simple Dictionaries.'!
For complete information evaluate "Object tgenCopyright."
=================================================
I implement a two dimensional LL(1) parser table with rows indexed by nonterminals, columns indexed by terminals, and with production table entries. At the top level I''m a Dictionary from nonterminals to rows; each row is a SetDictionary from terminals to productions. In deterministic tables (tables without multiple entries) the SetDictionaries can be (and are) converted into simple Dictionaries.'!
!LLParserTable methodsFor: 'testing'!
isDeterministic
self detect: [:row | row isDeterministic not]
ifNone: [^true].
^false! !
!LLParserTable methodsFor: 'private'!
newRow
^self rowClass new! !
!LLParserTable methodsFor: 'private'!
rowClass
^SetDictionary! !
!LLParserTable methodsFor: 'accessing'!
atNonterminal: nont andTerminal: term addProduction: prod
^row at: term ifAbsent: [self raiseNoTransitionExceptionErrorString: 'expecting one of ' , row keys printString , ' but encountered: ''' , term , '''']! !
For complete information evaluate "Object tgenCopyright."
=================================================
I am a final state of a finite state automata. If I''m part of a minimal deterministic fsa then it is possible that I represent several final states of some original non-deterministic fsa. My instance variables are used to distinguish between these various different final states. Final states for literal tokens (keywords) are represented by name in literalTokens. Final states for larger token classes are represented by TokenClassifications. When a token is recognized by this final state, it is first checked against the list of literal tokens. If not found, it is then classified as belonging to the one token class of which it is a member. The current implementation does not support overlapping token classes, hence, there can only really be one element in the OrderedCollection. However, in the future we hope to be able to support overlapping token classes.
Instance Variables:
literalTokens <Set of: String> - the literal tokens I recognize.
tokenClasses <OrderedCollection of: TokenClassification> - the token classes I recognize.'!
For complete information evaluate "Object tgenCopyright."
=================================================
I am a final state of a finite state automata. If I''m part of a minimal deterministic fsa then it is possible that I represent several final states of some original non-deterministic fsa. My instance variables are used to distinguish between these various different final states. Final states for literal tokens (keywords) are represented by name in literalTokens. Final states for larger token classes are represented by TokenClassifications. When a token is recognized by this final state, it is first checked against the list of literal tokens. If not found, it is then classified as belonging to the one token class of which it is a member. The current implementation does not support overlapping token classes, hence, there can only really be one element in the OrderedCollection. However, in the future we hope to be able to support overlapping token classes.
Instance Variables:
literalTokens <Set of: String> - the literal tokens I recognize.
tokenClasses <OrderedCollection of: TokenClassification> - the token classes I recognize.'!
!FSAFinalState methodsFor: 'initialization'!
init
super init.
self literalTokens: Set new.
self tokenClasses: OrderedCollection new! !
!FSAFinalState methodsFor: 'state accessing'!
literalTokens
^literalTokens! !
!FSAFinalState methodsFor: 'state accessing'!
literalTokens: argument
literalTokens := argument! !
!FSAFinalState methodsFor: 'state accessing'!
tokenClasses
^tokenClasses! !
!FSAFinalState methodsFor: 'state accessing'!
tokenClasses: argument
tokenClasses := argument! !
!FSAFinalState methodsFor: 'state transitions'!
transitionFor: aSymbol
"The default for final states is to not raise an exception
if no transitions are possible, rather, they answer nil."
For complete information evaluate "Object tgenCopyright."
=================================================
This class represents text views upon which no other view depends. Hence, another view will never be prevented from changing because of the status of a NonrelianceTextView.'!
For complete information evaluate "Object tgenCopyright."
=================================================
This class represents text views upon which no other view depends. Hence, another view will never be prevented from changing because of the status of a NonrelianceTextView.'!
!NonrelianceTextView methodsFor: 'updating'!
updateRequest
"Answer regarding whether the receiver may change."
newname := DialogView request: '(First letter must be upper case)' , (String with: Character cr) , 'New name for activity variable?' initialAnswer: oldname.
newname isEmpty
ifTrue: [^self]
ifFalse: [(selection aValidVariableName: newname)
ifFalse:
[TTMList speak: 'illegal variable name.'.
^self]
ifTrue:
[oldAV := avSelection copy.
avSelection at: 1 put: newname.
newAV := avSelection copy.
self changed: #avTransaction.
selection renameVariable: oldname asString to: newname asString.
selection
changeAllAVsAt: selection activitytree getRoot
from: oldAV
to: newAV.
selection renameActivityVariable: (oldAV at: 1)
to: (newAV at: 1).
self changed: #curSFList]]]! !
!TTMList methodsFor: 'variable access'!
avSelection: index
"If the selection has been changed, remember the new
selection."
| newSel |
selection == nil
ifFalse:
[newSel := index = 0
ifTrue: [nil]
ifFalse: [selection activityvariable at: index].
avSelection == newSel ifTrue: [^self].
avSelection := newSel]! !
!TTMList methodsFor: 'variable access'!
currentDirectory
^currentDirectory! !
!TTMList methodsFor: 'variable access'!
currentDirectory: aDirectory
currentDirectory := aDirectory! !
!TTMList methodsFor: 'variable access'!
dvAdd
"Add an data variable."
| newname |
newname := DialogView request: '(First letter must be upper case)' , (String with: Character cr) , 'New data variable name?'.
newname isEmpty
ifTrue: [^self]
ifFalse: [(selection aValidVariableName: newname)
ifFalse: [TTMList speak: 'illegal data variable name']
ifTrue: [(selection anExistingAV: newname)
= true | ((selection anExistingDV: newname)
= true)
ifTrue: [TTMList speak: newname , ' : variable name already in use']
ifFalse:
[selection
datavariable: newname
lrange: '0'
hrange: 'infinity'
initial: '0'.
selection updateSpecificIC.
self changed: #dvTransaction]]]! !
!TTMList methodsFor: 'variable access'!
dvChangeHigh
"Change upper bound of a data variable."
| high oldHigh initialAsNumber highAsNumber lowAsNumber |
dvSelection == nil
ifFalse:
[oldHigh := dvSelection at: 3.
high := DialogView request: 'New upper limit for data variable?' initialAnswer: oldHigh.
newname := DialogView request: '(First letter must be upper case)' , (String with: Character cr) , 'New name for data variable?' initialAnswer: oldname.
newname isEmpty
ifTrue: [^self]
ifFalse: [(selection aValidVariableName: newname)
ifFalse:
[TTMList speak: 'illegal variable name.'.
^self]
ifTrue:
[dvSelection at: 1 put: newname.
self changed: #dvTransaction.
selection renameVariable: oldname asString to: newname asString.
self changed: #curSFList]]]! !
!TTMList methodsFor: 'variable access'!
dvSelection: index
"If the selection has been changed, remember the new
For complete information evaluate "Object tgenCopyright."
=================================================
This abstract class provides the framework for both destructive and non-destructive tree traversals in which references to locally global objects are available without being explicitly passed as arguments.
Concrete subclasses must implement methods for traversing
childrenDo:
"Evaluate the argument block with each of my children."
updateChildrenUsing:
"Replace my children with the result of evaluating the argument block with the corresponding child."'!
For complete information evaluate "Object tgenCopyright."
=================================================
This abstract class provides the framework for both destructive and non-destructive tree traversals in which references to locally global objects are available without being explicitly passed as arguments.
Concrete subclasses must implement methods for traversing
childrenDo:
"Evaluate the argument block with each of my children."
updateChildrenUsing:
"Replace my children with the result of evaluating the argument block with the corresponding child."'!
!TreeNode methodsFor: 'traversing'!
childrenDo: aBlock
"Evaluate aBlock for each of my children.
This message should be reimplemented by my subclasses."
^self "default"! !
!TreeNode methodsFor: 'traversing'!
preorderDo: preBlock updateUsing: postBlock
"Perform a traversal on myself and my children. The preBlock is
evaluated when first entering a node. My children are replaced
with the results of the traversal. Thus, this message can be used
to generate objects or alter my structure, whereas postorderDo:
can only be used to examine my structure. This message may be
For complete information evaluate "Object tgenCopyright."
=================================================
I am an abstract class that provides the framework for creating objects from textual representations using a recursive descent parse.
This class is what used to be called ''NewCompiler'' in old TS implementations. It has not been rewritten to reflect its new place in the compiler framework in order to maintain compatibility with the old TS subclasses. When they are rewritten (when the Tektronix implementation is abandoned) this class should be also.
Instance Variables:
here <Object> the current token
hereType <Symbol> the "type" of the current token
hereMark <Integer> position in source stream (mark) where this token began
prevToken* <Integer> size in chars of the previous token parsed
prevMark <Integer> mark of previous token
class <Class> provides a context for the text being parsed
encoder <Encoder> which uses tables to decode tokens
parseNode <ParseNode> intermediate result of current parse (for use by subclasses)
lastTempMark <Integer> mark of last temp;
points to vert bar, or last char of pattern if no temps declared
correctionDelta <Integer> offset of corrected code relative to source stream
owing to interactive corrections so far.
* inherited from AbstractParser, but with new semantics.'!
For complete information evaluate "Object tgenCopyright."
=================================================
I am an abstract class that provides the framework for creating objects from textual representations using a recursive descent parse.
This class is what used to be called ''NewCompiler'' in old TS implementations. It has not been rewritten to reflect its new place in the compiler framework in order to maintain compatibility with the old TS subclasses. When they are rewritten (when the Tektronix implementation is abandoned) this class should be also.
Instance Variables:
here <Object> the current token
hereType <Symbol> the "type" of the current token
hereMark <Integer> position in source stream (mark) where this token began
prevToken* <Integer> size in chars of the previous token parsed
prevMark <Integer> mark of previous token
class <Class> provides a context for the text being parsed
encoder <Encoder> which uses tables to decode tokens
parseNode <ParseNode> intermediate result of current parse (for use by subclasses)
lastTempMark <Integer> mark of last temp;
points to vert bar, or last char of pattern if no temps declared
correctionDelta <Integer> offset of corrected code relative to source stream
owing to interactive corrections so far.
* inherited from AbstractParser, but with new semantics.'!
For complete information evaluate "Object tgenCopyright."
=================================================
I am an abstract class of scanner that scans a source string and breaks it up into tokens using a minimal deterministic finite-state automata (FSA). Each token is also given a type by its associated final state in the FSA. Specific FSAs are stored in class instance variables of my concrete subclasses.
Instance Variables:
fsa <FSAState> - a local reference to the token recognizer, in minimal deterministic form, for this class of scanner.
For complete information evaluate "Object tgenCopyright."
=================================================
I am an abstract class of scanner that scans a source string and breaks it up into tokens using a minimal deterministic finite-state automata (FSA). Each token is also given a type by its associated final state in the FSA. Specific FSAs are stored in class instance variables of my concrete subclasses.
Instance Variables:
fsa <FSAState> - a local reference to the token recognizer, in minimal deterministic form, for this class of scanner.
For complete information evaluate "Object tgenCopyright."
=================================================
I am an abstract class of scanner that scans a source string and breaks it up into tokens using a character type table and hand-coded scanner methods. Specific type tables are stored in class instance variables of my concrete subclasses.
Instance Variables:
charTypeTable <Array of: Symbol> - a local reference to the type table for this class of scanner; the ascii value of each character is mapped to a symbol token type.
For complete information evaluate "Object tgenCopyright."
=================================================
I am an abstract class of scanner that scans a source string and breaks it up into tokens using a character type table and hand-coded scanner methods. Specific type tables are stored in class instance variables of my concrete subclasses.
Instance Variables:
charTypeTable <Array of: Symbol> - a local reference to the type table for this class of scanner; the ascii value of each character is mapped to a symbol token type.
'!
!HandCodedScanner methodsFor: 'state accessing'!
charTypeTable
^charTypeTable! !
!HandCodedScanner methodsFor: 'state accessing'!
charTypeTable: argument
charTypeTable := argument! !
!HandCodedScanner methodsFor: 'initialization'!
init
super init.
self charTypeTable: self myTypeTable! !
!HandCodedScanner methodsFor: 'accessing'!
endOfInputToken
"Answer a token representing the end of the input."
^nil! !
!HandCodedScanner methodsFor: 'accessing'!
endOfInputTokenType
"Answer the token type representing the end of the input."
^#doIt! !
!HandCodedScanner methodsFor: 'accessing'!
myTypeTable
^self class charTypeTable! !
!HandCodedScanner methodsFor: 'testing'!
atStartOfComplexToken
"Answer true if the first character of the tokenType is an $x and false otherwise."
^(self tokenType at: 1)
= $x! !
!HandCodedScanner methodsFor: 'scanning'!
scanToken
"Scan the next token and compute its token type. This may be
overridden in subclasses for efficiency and customization."
For complete information evaluate "Object tgenCopyright."
=================================================
It is often helpful to create a node that has a arbitrary (but flat) collection of nodes as a child. My instances provide containers for these "collection children". In other words, I am a collection that acts like a single parse tree node.'!
For complete information evaluate "Object tgenCopyright."
=================================================
It is often helpful to create a node that has a arbitrary (but flat) collection of nodes as a child. My instances provide containers for these "collection children". In other words, I am a collection that acts like a single parse tree node.'!
For complete information evaluate "Object tgenCopyright."
=================================================
This is an abstract class that provides a framework for building parse trees during parsing. Parse trees are built in a bottom-up fashion during parsing by processing key productions, and with the help of a stack. In general, a key production has the form:
A -> N1 N2 ... Nk => symbol
where A and the Ni are nonterminals (terminals may be interspersed freely in the right-hand side) and symbol is the production directive (or translation symbol). Since trees are built bottom-up, the information flow in a production is from the right-hand side to the left-hand side. When a production is ready to be processed, the top of the stack contains objects (parse trees) associated with the right-hand-side nonterminals of the production. Processing a production involves replacing these objects with a single object representing (associated with) the left-hand-side nonterminal. This can be thought of as computing a value for A as a function of the values of the Ni''s, i.e. value(A) = fcn(value(N1), value(N2), ..., value(Nk)). Default functions are defined in my concrete subclasses but users may define their own production processing functions by creating a new subclass and implementing appropriate messages. This enables users to have direct control over exactly how parse trees are built.
Instance Variables:
stack <Stack> - holds intermediate node values during production processing.'!
For complete information evaluate "Object tgenCopyright."
=================================================
This is an abstract class that provides a framework for building parse trees during parsing. Parse trees are built in a bottom-up fashion during parsing by processing key productions, and with the help of a stack. In general, a key production has the form:
A -> N1 N2 ... Nk => symbol
where A and the Ni are nonterminals (terminals may be interspersed freely in the right-hand side) and symbol is the production directive (or translation symbol). Since trees are built bottom-up, the information flow in a production is from the right-hand side to the left-hand side. When a production is ready to be processed, the top of the stack contains objects (parse trees) associated with the right-hand-side nonterminals of the production. Processing a production involves replacing these objects with a single object representing (associated with) the left-hand-side nonterminal. This can be thought of as computing a value for A as a function of the values of the Ni''s, i.e. value(A) = fcn(value(N1), value(N2), ..., value(Nk)). Default functions are defined in my concrete subclasses but users may define their own production processing functions by creating a new subclass and implementing appropriate messages. This enables users to have direct control over exactly how parse trees are built.
Instance Variables:
stack <Stack> - holds intermediate node values during production processing.'!
!ParseTreeBuilder methodsFor: 'initialization'!
init
self stack: Stack new! !
!ParseTreeBuilder methodsFor: 'state accessing'!
stack
^stack! !
!ParseTreeBuilder methodsFor: 'state accessing'!
stack: argument
stack := argument! !
!ParseTreeBuilder methodsFor: 'accessing'!
popStack
^self stack pop! !
!ParseTreeBuilder methodsFor: 'accessing'!
pushStack: anObject
^self stack push: anObject! !
!ParseTreeBuilder methodsFor: 'accessing'!
result
"Answer the root of the tree build by this tree builder."
For complete information evaluate "Object tgenCopyright."
=================================================
I build parse trees by creating specific objects for each kind of node as indicated by the parser directives in grammar productions. Parser directives currently fall into one of three groups: node (class) names, special directives, and arbitrary message selectors. For a node name, a new instance of the specified node is created and given the values associated with the right-hand side nonterminals, if any, as its children. The special directive ''nil'' simply returns nil. The directive liftRightChild adds any nodes preceeding the right-most node as children to the right-most node, and returns the right-most node. The directive liftLeftChild works in an analogous fashion. Arbitrary message selectors must take the same number of arguments as there are right-hand-side nodes and are invoked as a builder message, thus allowing users to define their own tree-building messages.
Productions of the form ''A -> <tc> => symbol'' are treated specially. The symbol can be either a node name or a one-argument message selector. If it is a node name then create a new instance of that node with the specified attribute value. If it is a message selector then invoke the corresponding operation on the builder with the specified value.
Instance Variables:
shamMode <Boolean> - If true DerivationTreeNode-based ASTs are built, otherwise specific ParseTreeNode-based ASTs are built.'!
For complete information evaluate "Object tgenCopyright."
=================================================
I build parse trees by creating specific objects for each kind of node as indicated by the parser directives in grammar productions. Parser directives currently fall into one of three groups: node (class) names, special directives, and arbitrary message selectors. For a node name, a new instance of the specified node is created and given the values associated with the right-hand side nonterminals, if any, as its children. The special directive ''nil'' simply returns nil. The directive liftRightChild adds any nodes preceeding the right-most node as children to the right-most node, and returns the right-most node. The directive liftLeftChild works in an analogous fashion. Arbitrary message selectors must take the same number of arguments as there are right-hand-side nodes and are invoked as a builder message, thus allowing users to define their own tree-building messages.
Productions of the form ''A -> <tc> => symbol'' are treated specially. The symbol can be either a node name or a one-argument message selector. If it is a node name then create a new instance of that node with the specified attribute value. If it is a message selector then invoke the corresponding operation on the builder with the specified value.
Instance Variables:
shamMode <Boolean> - If true DerivationTreeNode-based ASTs are built, otherwise specific ParseTreeNode-based ASTs are built.'!
For complete information evaluate "Object tgenCopyright."
=================================================
This concrete class is used for building derivation trees for a parse. It uses homogeneous DerivationTreeNodes for all nodes and a specialized production processor.'!
For complete information evaluate "Object tgenCopyright."
=================================================
This concrete class is used for building derivation trees for a parse. It uses homogeneous DerivationTreeNodes for all nodes and a specialized production processor.'!
For complete information evaluate "Object tgenCopyright."
=================================================
I am an abstract class that provides the framework for parse tree nodes, basically just a reminder that the following messages may need to be implemented by concrete subclasses:
For complete information evaluate "Object tgenCopyright."
=================================================
I am an abstract class that provides the framework for parse tree nodes, basically just a reminder that the following messages may need to be implemented by concrete subclasses:
For complete information evaluate "Object tgenCopyright."
=================================================
I represent an arbitrary node in a derivation or abstract tree. (It would be nice to expand this concept so that heterogeneous parse trees could be built.)
Instance Variables:
symbol <String> - node attribute.
children <OrderedCollection of: DerivationTreeNode>'!
For complete information evaluate "Object tgenCopyright."
=================================================
I represent an arbitrary node in a derivation or abstract tree. (It would be nice to expand this concept so that heterogeneous parse trees could be built.)
Instance Variables:
symbol <String> - node attribute.
children <OrderedCollection of: DerivationTreeNode>'!
For complete information evaluate "Object tgenCopyright."
=================================================
I represent one production of a context-free grammar. I am responsible for some parts of the first/follow set computation algorithm and for converting myself between various related representations (e.g. LR(0) items).
For complete information evaluate "Object tgenCopyright."
=================================================
I represent one production of a context-free grammar. I am responsible for some parts of the first/follow set computation algorithm and for converting myself between various related representations (e.g. LR(0) items).
For complete information evaluate "Object tgenCopyright."
=================================================
I add a translation attribute to context-free grammar productions so that I can be used to build simple transduction grammars (or syntax-directed translation scheme). Transduction grammars are used to build abstract syntax trees rather than derivation trees during parsing. For more information, refer to Chapter 7. ("Syntax-Directed Translation") in {\em Compiler Construction: Theory and Practice} by Barrett, Bates, Gustafson, and Couch.
Instance Variables:
translationSymbol <String> - used as basis for translation node when parsing.'!
For complete information evaluate "Object tgenCopyright."
=================================================
I add a translation attribute to context-free grammar productions so that I can be used to build simple transduction grammars (or syntax-directed translation scheme). Transduction grammars are used to build abstract syntax trees rather than derivation trees during parsing. For more information, refer to Chapter 7. ("Syntax-Directed Translation") in {\em Compiler Construction: Theory and Practice} by Barrett, Bates, Gustafson, and Couch.
Instance Variables:
translationSymbol <String> - used as basis for translation node when parsing.'!
!TransductionGrammarProduction methodsFor: 'parse tree building'!
computeResultNodeFor: builder withArgNodes: nodes
"Three kinds of translation symbols are currently supported: node names, special
directives, and arbitrary message selectors. For a node name, a new instance of
the specified node is created and given nodes, if any, as its children. The special
directive 'nil' simply returns nil. The directive liftRightChild adds any nodes
preceeding the right-most node as children to the right-most node, and returns
the right-most node. The directive liftLeftChild works in an analogous fashion.
Arbitrary message selectors must take the number of arguments in nodes and
are invoked as a builder message, thus allowing users to define their own
tree-building messages."
| symbol node |
symbol := self translationSymbol asSymbol.
symbol first isUppercase ifTrue: [^nodes isEmpty
ifTrue: [builder makeNewNode: symbol]
ifFalse: [builder makeNewNode: symbol withChildren: nodes]].
symbol = self epsilonSymbol ifTrue: [^builder answerNil].
symbol = self rightLiftSymbol
ifTrue:
[nodes size < 2 ifTrue: [self error: 'Only use liftRightChild when there are at least two right-hand-side nonterminals.'].
"special case for building lists ending with epsilon"
(nodes size = 2 and: [nodes last isNil])
ifTrue: [^builder answerArgument: nodes first].
node := nodes removeLast.
^builder addChildrenFirst: nodes to: node].
symbol = self leftLiftSymbol
ifTrue:
[nodes size < 2 ifTrue: [self error: 'Only use liftLeftChild when there are at least two right-hand-side nonterminals.'].
"special case for building lists beginning with epsilon"
(nodes size = 2 and: [nodes first isNil])
ifTrue: [^builder answerArgument: nodes last].
node := nodes removeFirst.
^builder addChildrenLast: nodes to: node].
symbol numArgs = nodes size ifFalse: [self error: 'Translation message selectors must have the same number of arguments as right-hand-side nonterminals.'].
nodes isEmpty ifTrue: [^builder perform: symbol].
"It may be more efficient to check the number of arguments and use
perform:with:, etc., but probably not."
^builder perform: symbol withArguments: nodes asArray! !
!TransductionGrammarProduction methodsFor: 'parse tree building'!
computeResultNodeFor: builder withTokenClassValue: value
"I am assumed to be a production of the form 'A -> <tc> => symbol'.
The symbol can be either a node name or a one-argument message selector.
If it is a node name then create a new instance of that node with the specified
attribute value. If it is a message selector then invoke the corresponding
operation on the builder with the specified value."
| symbol |
symbol := self translationSymbol asSymbol.
symbol first isUppercase
ifTrue: [^builder makeNewNode: symbol withAttribute: value]
ifFalse: [symbol numArgs = 1
ifTrue: [^builder perform: symbol with: value]
ifFalse: [self error: 'Expected either a node name or a one argument
For complete information evaluate "Object tgenCopyright."
=================================================
I represent a node in an LR parser characteristic finite state machine.
Instance Variables:
edgeLabelMap <Dictionary from: symbols to: successors> - overridden from EdgeLabeledDigraphNode for efficiency since only deterministic FSAs are constructed.
reduceMap <SetDictionary from: symbols to: productions>'!
For complete information evaluate "Object tgenCopyright."
=================================================
I represent a node in an LR parser characteristic finite state machine.
Instance Variables:
edgeLabelMap <Dictionary from: symbols to: successors> - overridden from EdgeLabeledDigraphNode for efficiency since only deterministic FSAs are constructed.
reduceMap <SetDictionary from: symbols to: productions>'!
!LRParserState methodsFor: 'initialization'!
init
super init.
self edgeLabelMap: Dictionary new. "overrides use of SetDictionary in superclass"
self reduceMap: SetDictionary new! !
!LRParserState methodsFor: 'state accessing'!
reduceMap
^reduceMap! !
!LRParserState methodsFor: 'state accessing'!
reduceMap: argument
reduceMap := argument! !
!LRParserState methodsFor: 'exception handling'!
standardErrorString
^'unexpected token encountered: '! !
!LRParserState methodsFor: 'printing'!
printOn: aStream
super printOn: aStream.
aStream cr.
self reduceMap printOn: aStream! !
!LRParserState methodsFor: 'lalr analysis'!
appendHashTo: sym
"Answer a new nonterminal or terminal with my hash value appended."
For complete information evaluate "Object tgenCopyright."
=================================================
I implement a two dimensional LL(1) parser table with rows indexed by nonterminals, columns indexed by terminals, and with production table entries. At the top level I''m a Dictionary from nonterminals to rows; each row is a SetDictionary from terminals to productions. In deterministic tables (tables without multiple entries) the SetDictionaries can be (and are) converted into simple Dictionaries.'!
For complete information evaluate "Object tgenCopyright."
=================================================
I implement a two dimensional LL(1) parser table with rows indexed by nonterminals, columns indexed by terminals, and with production table entries. At the top level I''m a Dictionary from nonterminals to rows; each row is a SetDictionary from terminals to productions. In deterministic tables (tables without multiple entries) the SetDictionaries can be (and are) converted into simple Dictionaries.'!
!LLParserTable methodsFor: 'testing'!
isDeterministic
self detect: [:row | row isDeterministic not]
ifNone: [^true].
^false! !
!LLParserTable methodsFor: 'private'!
newRow
^self rowClass new! !
!LLParserTable methodsFor: 'private'!
rowClass
^SetDictionary! !
!LLParserTable methodsFor: 'accessing'!
atNonterminal: nont andTerminal: term addProduction: prod
^row at: term ifAbsent: [self raiseNoTransitionExceptionErrorString: 'expecting one of ' , row keys printString , ' but encountered: ''' , term , '''']! !
For complete information evaluate "Object tgenCopyright."
=================================================
I am a final state of a finite state automata. If I''m part of a minimal deterministic fsa then it is possible that I represent several final states of some original non-deterministic fsa. My instance variables are used to distinguish between these various different final states. Final states for literal tokens (keywords) are represented by name in literalTokens. Final states for larger token classes are represented by TokenClassifications. When a token is recognized by this final state, it is first checked against the list of literal tokens. If not found, it is then classified as belonging to the one token class of which it is a member. The current implementation does not support overlapping token classes, hence, there can only really be one element in the OrderedCollection. However, in the future we hope to be able to support overlapping token classes.
Instance Variables:
literalTokens <Set of: String> - the literal tokens I recognize.
tokenClasses <OrderedCollection of: TokenClassification> - the token classes I recognize.'!
For complete information evaluate "Object tgenCopyright."
=================================================
I am a final state of a finite state automata. If I''m part of a minimal deterministic fsa then it is possible that I represent several final states of some original non-deterministic fsa. My instance variables are used to distinguish between these various different final states. Final states for literal tokens (keywords) are represented by name in literalTokens. Final states for larger token classes are represented by TokenClassifications. When a token is recognized by this final state, it is first checked against the list of literal tokens. If not found, it is then classified as belonging to the one token class of which it is a member. The current implementation does not support overlapping token classes, hence, there can only really be one element in the OrderedCollection. However, in the future we hope to be able to support overlapping token classes.
Instance Variables:
literalTokens <Set of: String> - the literal tokens I recognize.
tokenClasses <OrderedCollection of: TokenClassification> - the token classes I recognize.'!
!FSAFinalState methodsFor: 'initialization'!
init
super init.
self literalTokens: Set new.
self tokenClasses: OrderedCollection new! !
!FSAFinalState methodsFor: 'state accessing'!
literalTokens
^literalTokens! !
!FSAFinalState methodsFor: 'state accessing'!
literalTokens: argument
literalTokens := argument! !
!FSAFinalState methodsFor: 'state accessing'!
tokenClasses
^tokenClasses! !
!FSAFinalState methodsFor: 'state accessing'!
tokenClasses: argument
tokenClasses := argument! !
!FSAFinalState methodsFor: 'state transitions'!
transitionFor: aSymbol
"The default for final states is to not raise an exception
if no transitions are possible, rather, they answer nil."
For complete information evaluate "Object tgenCopyright."
=================================================
This class represents text views upon which no other view depends. Hence, another view will never be prevented from changing because of the status of a NonrelianceTextView.'!
For complete information evaluate "Object tgenCopyright."
=================================================
This class represents text views upon which no other view depends. Hence, another view will never be prevented from changing because of the status of a NonrelianceTextView.'!
!NonrelianceTextView methodsFor: 'updating'!
updateRequest
"Answer regarding whether the receiver may change."
newname := DialogView request: '(First letter must be upper case)' , (String with: Character cr) , 'New name for activity variable?' initialAnswer: oldname.
newname isEmpty
ifTrue: [^self]
ifFalse: [(selection aValidVariableName: newname)
ifFalse:
[TTMList speak: 'illegal variable name.'.
^self]
ifTrue:
[oldAV := avSelection copy.
avSelection at: 1 put: newname.
newAV := avSelection copy.
self changed: #avTransaction.
selection renameVariable: oldname asString to: newname asString.
selection
changeAllAVsAt: selection activitytree getRoot
from: oldAV
to: newAV.
selection renameActivityVariable: (oldAV at: 1)
to: (newAV at: 1).
self changed: #curSFList]]]! !
!TTMList methodsFor: 'variable access'!
avSelection: index
"If the selection has been changed, remember the new
selection."
| newSel |
selection == nil
ifFalse:
[newSel := index = 0
ifTrue: [nil]
ifFalse: [selection activityvariable at: index].
avSelection == newSel ifTrue: [^self].
avSelection := newSel]! !
!TTMList methodsFor: 'variable access'!
currentDirectory
^currentDirectory! !
!TTMList methodsFor: 'variable access'!
currentDirectory: aDirectory
currentDirectory := aDirectory! !
!TTMList methodsFor: 'variable access'!
dvAdd
"Add an data variable."
| newname |
newname := DialogView request: '(First letter must be upper case)' , (String with: Character cr) , 'New data variable name?'.
newname isEmpty
ifTrue: [^self]
ifFalse: [(selection aValidVariableName: newname)
ifFalse: [TTMList speak: 'illegal data variable name']
ifTrue: [(selection anExistingAV: newname)
= true | ((selection anExistingDV: newname)
= true)
ifTrue: [TTMList speak: newname , ' : variable name already in use']
ifFalse:
[selection
datavariable: newname
lrange: '0'
hrange: 'infinity'
initial: '0'.
selection updateSpecificIC.
self changed: #dvTransaction]]]! !
!TTMList methodsFor: 'variable access'!
dvChangeHigh
"Change upper bound of a data variable."
| high oldHigh initialAsNumber highAsNumber lowAsNumber |
dvSelection == nil
ifFalse:
[oldHigh := dvSelection at: 3.
high := DialogView request: 'New upper limit for data variable?' initialAnswer: oldHigh.
newname := DialogView request: '(First letter must be upper case)' , (String with: Character cr) , 'New name for data variable?' initialAnswer: oldname.
newname isEmpty
ifTrue: [^self]
ifFalse: [(selection aValidVariableName: newname)
ifFalse:
[TTMList speak: 'illegal variable name.'.
^self]
ifTrue:
[dvSelection at: 1 put: newname.
self changed: #dvTransaction.
selection renameVariable: oldname asString to: newname asString.
self changed: #curSFList]]]! !
!TTMList methodsFor: 'variable access'!
dvSelection: index
"If the selection has been changed, remember the new