Commits

Ryan Macnak committed bfd04fe

Compiler cleanup: replace use of AST type checking vistors with auto isFoo.

  • Participants
  • Parent commits 7539e6e

Comments (0)

Files changed (1)

File Newspeak3Compilation.ns3

-Newspeak3
-
-'Newspeak3'
-
-
-
-class Newspeak3Compilation
- usingPlatform: platform
- newspeakParser: ns3Parser <Newspeak3Parsing>
- mirrorLib: mirrors = NewspeakObject (
-"This is the Newspeak compilation module. It includes the Newspeak compiler (Compiler) as well as a number of other classes used in compilation. For a  detailed overview of compilation see Compiler.
-
-Classes that do not require access to the state of a compiler are defined at the module level, as siblings of the compiler.  This is true even if the class defines a phase of compilation, like the ScopeBuilder.
-
-Relation to parsing:
-
-Note that this module does not include a parser or AST classes.  These have utility independent of compilation, and so are available as a separate parsing module. This module requires such a parsing module as parameter. It uses this parameter to create a parser for compilation, and to subclass certain AST classes and tools for its own purposes.
-
-The parser is instantiated upon module creation and stored in a module slot. We expect a Newspeak parser to be purely functional; hence we may share it among all compiler instances. It's not clear if this is a valid assumption in the long term.
-
-Separating the parsing module makes it easy to change parsing strategies (though one could also define parsing here and override it in a subclass).
-
-Other parameters:
-
-The module uses some general purpose facilities which it expects to obtain from the underlying platform via the platform parameter.
-In addition, a mirror library should be provided, as the compiler operates by querying and creating various mirrors. See the documentation of class Compiler for more discussion of the use of mirrors.
-
-Copyright 2008 Cadence Design Systems, Inc.
-Copyright 2010 Gilad Bracha, Felix Geller and Ryan Macnak
-Copyright 2011 Matthias Kleine, Ryan Macnak and Cadence Design Systems
-   
-   Licensed under the Apache License, Version 2.0 (the ''License''); you may not use this file except in compliance with the License.  You may obtain a copy of the License at  http://www.apache.org/licenses/LICENSE-2.0"
-	|
-      
-	Collection = platform collections Collection.
-	Dictionary = platform collections Dictionary.
-	IdentityDictionary = platform collections IdentityDictionary.
-	OrderedCollection = platform collections OrderedCollection.
-	Set = platform collections Set.
-	SortedList = platform collections SortedCollection.
-	
-	Parser = ns3Parser Parser.
-	astModule = ns3Parser ASTModule.
-	
-	ASTTool = astModule ASTTool.
-      ASTCopier = astModule ASTCopier.
-	ASTTraverser = astModule ASTTraverser.
-      SuperFalseVisitor = astModule FalseVisitor.
-
-      AST = astModule AST.
-	AssignmentAST = astModule AssignmentAST.
-	BlockAST = astModule BlockAST.
-	CascadedSendAST = astModule CascadedSendAST.
-	CodeBodyAST = astModule CodeBodyAST.
-	MessageAST = astModule MessageAST.
-      MessagePatternAST = astModule MessagePatternAST.
-	MethodAST = astModule MethodAST.
-	MutableSlotDefAST = astModule MutableSlotDefAST.
-	NormalSendAST = astModule NormalSendAST.
-	NumberAST = astModule NumberAST.
-	ReturnStatAST = astModule ReturnStatAST.
-      SendAST = astModule SendAST.
-	SetterSendAST = astModule SetterSendAST.
-	StringAST = astModule StringAST.
-	SymbolAST = astModule SymbolAST.
-	TupleAST = astModule TupleAST.
-      VarDeclAST = astModule VarDeclAST.
-	VariableAST = astModule VariableAST.
-	
-	Class = platform blackMarket Kernel Class.	
-	Language = platform blackMarket NsMultilanguage Language.
-	LanguageCompiler = platform blackMarket NsMultilanguage LanguageCompiler.
-	Pragma = platform blackMarket Pragma.
-
-	"{Newspeak-core-mirror}"  "a bunch of mirror stuff"
-	SystemMetadata = mirrors SystemMetadata.
-	CompiledMixinMirror = mirrors CompiledMixinMirror.
-	LowLevelMixinMirror = mirrors LowLevelMixinMirror.
-	LowLevelMethodMirror = mirrors LowLevelMethodMirror.
-	InstanceVariableMirror = mirrors InstanceVariableMirror.
-
-	ClassDeclarationMirror = mirrors ClassDeclarationMirror.
-	
-	"{Newsqueak-mixins}"
-	Mixin = platform blackMarket NewsqueakMixins Mixin.
-	
-	"Module variables"
-	parser = Parser new.
-	|
-)
-
-(
-
-
-
-class SymbolTableEntry for: datum =  (
-| 
-  sym  
-  data = datum first.  
-  depth = datum last.  
-|
-)
-
-('as yet unclassified'
-
-isMethodNode = (^self data  isMethodNode)
-
-
-
-'testing'
-
-isMessagePatternNode = (^self data  isMessagePatternNode)
-
-
-
-isVarDeclNode = (^self data isVarDeclNode)
-
-
-
-) : (
-
-'as yet unclassified'
-
-forMessage: selector atDepth: depth = (
-
-
-
-)
-
-
-
-class SemanticVarDecl decl: d <VarDeclAST> = SymbolTableEntry for: d (
-"Semantic info for a variable: slot, local or parameter."
-|
-  offset <Integer>
-  remote ::= false.
-  remoteVector <SemanticVarDecl>
-|
-)
-
-('as yet unclassified'
-
-isTemporaryAST ^ <Boolean> = (
-
-
-
-setIndex: i <Integer> InVector: v <VarDeclAST> = (
-
-
-
-variableClass ^ <Class> = (
-
-
-
-)
-
-
-
-class Compiler = LanguageCompiler  (
-"The compiler has three main entry points: compileClassSource:Within:, compileClassHeader: within: and compileMethodSource:within:. These compile an entire class declaration, a class header, and a method, respectively. 
-
-The compiler returns low level (e.g., VM level) objects representing the results of compilation.
-These results are described in some detail in the individual methods. The results are never installed by the compiler. The compiler does not know or care whether it is running in the service of a live system. If the compiler is invoked from such a system, the caller may choose to install the results. This should be done as an atomic modification, since the results may be interdependent (e.g., a nested class and its enclosing class). 
-
-Compilation begins with parsing, followed by a pass on the resulting AST to compute the scope. The scope is stored as a shadow tree of the AST. Specifically, the slot scopeMap stores a dictionary mapping AST nodes to scopes. This mapping is computed by ScopeBuilder.
-
-Optimization note: 
-This can be optimized, so that we only compute the scope of a class side, and then use it as a basis for computing the scope of each method. This would prevent us from holding onto the scopes for all methods when compiling a class. Likewise, we can avoid holding onto the scopes of all nested classes. 
-** end note
-
-When compiling an individual method, we also rewrite its AST into a lower level AST, and submit that to the AST2ByteCodeCompiler, which produces byte code.  If we are compiling a class declaration or a class header, we compute the overall structure of the resulting mixin, including any required synthetic members.
-
-The NS2 implementation involves a considerable amount of synthetic code, dealing with accessors, nested classes, slot initialization, superclass initialization and the primary constructor. 
-
-Nested classes are distinct for every instance of an outer class. Hence, every outer class has synthetic fields that hold the class objects for its nested classes. These fields are always accessed by a getter method which lazily initializes the field. The name of the getter method is the simple name of the inner class. The field, in contrast, is named X_slot, where X is the fully qualified name of the inner class' mixin. This is necessary to prevent it from clashing with nested classes with the same simple name elsewhere in the hierarchy. See accessorStringForNestedClassNamed:fullName:superName: .
-
-The creation of classes is based on producing a low level mixin mirror for the class.
-
-Nested classes also have an enclosingObject slot pointing at the object that created them, and a getter for it. See ensureEnclosingObjectAccessFor:.
-
-The primary constructor induces a synthetic class method of the same name, which calls a synthetic  instance method of the same name on a freshly created instance. Within that instance method is the code for all the slot initializers, as well as the superclass constructor call. See processConstructorFor:inClass:."
-
-|
-
-scopeMap <Dictionary[Scope, AST]> ::= Dictionary new.
-scope <Scope>
-scopeStack <OrderedCollection[Scope]> = OrderedCollection new.
-literalTable <IdentityDictionary[Symbol, Integer]>
-rewriter = Rewriter new.
-methodCompiler = AST2ByteCodeCompiler new.
-currentDepth <Integer> "The lexical nesting level of the current class; 
-							top level classes are at level 0"
-
-language = Delay computation: [Language newspeak3].
-	 
-|
-)
-
-(
-
-
-
-class ScopeBuilder nestedIn: initialScope <Scope> atLevel: initialDepth <Integer> = ASTTool  ("The scope builder is a visitor on the AST. It computes a tree of scopes that shadows the AST itself.  More precisely, it computes a mapping from ASTs to their scopes. This allows us to get to the appropriate scope for an abstract syntax node without pollluting the AST with extraneous data like scopes.
-
-We could associate each node in the AST with the scope in which it is found, but this would be overkill. Instead, only nodes that actually introduce new scopes (such as class sides, message patterns, code bodies and blocks) actually get mapped in this manner. The intent is that later phases of compilation will visit the tree and look up the scopes at the points where they are introduced.
-
-The builder starts at a given node, in the context of some mixin, described by a mirror.  This is because, in an incremental environment, we may not have the complete AST for a module, but instead be asked to process a part of that module, such as a nested class, slot definition or method. The surrounding scope can be computed from the mirror representing the immediately enclosing mixin.
-
-Then we traverse the tree, creating and populating new scopes as needed. We maintain a stack of scopes (scopeStack) that initially contains only the surrounding scope.  Scopes get pushed on to the stack when we encounter a node that introduces a scope, and popped when we finish with that node. The scopes are chained to their super scopes (the scope below them on the stack).
-
-A possible optimization is to avoid a traversal of an entire side of a class.
-One can process only a side without its subtrees (i.e., methods and nested classes). These can be visited later,  as long as we ensure that the processing of the subtree begins with a proper super scope on top of the scope stack."
-| 
-  scopeStack = OrderedCollection new.
-  
-  currentDepth ::= initialDepth. "The lexical nesting level of the class declaration currently 
-						being visited; top level classes are level 0"
-|
-
-pushScope: initialScope.
-)
-
-('as yet unclassified'
-
-buildScopeFor: m <MixinMirror> ^ <Scope> = (
-
-
-
-classNode: aNode <ClassDeclarationAST> = (
    		  v isMutable ifTrue:[vs at: (v name asString, ':') asSymbol put: (SymbolTableEntry for:{MessagePatternAST new selector: (v name asString, ':') asSymbol. currentDepth}) "setter"]
    	 ].
  	aNode instanceSide apply: self.
  	aNode classSide apply: self.
-
-
-
-codeBodyNode: aNode <CodeBodyAST> = (
                          ts at: t name put: (SemanticVarDecl decl:{t slotDecl. currentDepth}); " getter"
                              at: (t name asString, ':') asSymbol put: t slotDecl "setter"
                         ].
-
-
-
-enclosingMixinsOf: m <MixinMirror> ^ <Collection[MixinMirror]> = (
-
-
-
-keywordPatternNode: n = (
-
-
-
-literalPatternNode: n = (
-
-
-
-mixinClassNode: aNode = (
-
-
-
-prvtScopeFor: c <MixinMirror> ^<Scope> = (
-
-
-
-selectorsFor: m <MixinMirror> ^ <Collection[Symbol]> = (
-
-
-
-setterSendNode: aNode <SetterSendAST> = (
-
-
-
-sideNode: aNode <SideAST> = (
                        c methods do:[:m <MethodAST> | m apply: self]
        ].
-
-
-
-wildcardPatternNode: node = (
-
-
-
-'node traversal'
-
-blockNode: aNode <BlockAST> = (
-
-
-
-cascadedSendNode: aNode <CascadedSendAST> = (
-
-
-
-charNode: aNode <CharAST> = (
-
-
-
-classHeaderNode: aNode = (
-
-
-
-messageNode: aNode <MessageAST> = (
-
-
-
-messagePatternNode: aNode <MessagePatternAST> = (
-
-
-
-methodNode: aNode <MethodAST> = (
-
-
-
-mixinApplication: node <MixinApplicationAST> = (
-
-
-
-normalSendNode: aNode <NormalSendAST> = (
-
-
-
-numberNode: aNode <NumberAST> = (
-
-
-
-returnStatNode: aNode <ReturnStatAST> = (
-
-
-
-stringNode: aNode <StringAST> = (
-
-
-
-symbolNode: aNode <SymbolAST> = (
-
-
-
-tupleNode: aNode <TupleAST> = (
-
-
-
-varDeclNode: aNode <VarDeclAST> = (
-
-
-
-variableNode: aNode <VariableAST> = (
   assert:[aNode name = #'_here' or:[isPseudoVariableNode: aNode]]
-
-
-
-'private'
-
-currentScope ^ <Scope> = (
  ^scopeStack last
-
-
-
-isPseudoVariableNode: aNode <VariableAST> ^ <Boolean> = (
-
-
-
-nestScope: s <Scope> = (
  s superScope: currentScope.
  pushScope: s
-
-
-
-popScope ^ <Scope> = (
   ^scopeStack removeLast
-
-
-
-pushScope: s <Scope> = (
  scopeStack addLast: s
-
-
-
-'access'
-
-visitMethod: aNode <MethodAST> within: m <MixinMirror> ^ <Dictionary[AST, Scope]> = (
   ^visitNode: aNode within: m
-
-
-
-visitNode: aNode <AST> within: m <MixinMirror> ^ <Dictionary[AST, Scope]> = (
   pushScope:(buildScopeFor: m).
   aNode apply: self.
   ^scopeMap
-
-
-
-) : (
-
-'as yet unclassified'
-
-new ^ <Instance> = (
-
-
-
-)
-
-
-
-class AST2ByteCodeCompiler = ASTTool (
-"The compiler is a visitor on an AST that has been processed by the rewriter.
-It is a subtype of  ASTTool[Self] - that is, its methods do not return individual results, but instead
-side effect state within the compiler.
-
-The compiler decides what instructions to generate at a somewhat abstract level, and asks
-a code generator object to actually produce the instruction stream.
-
-The code generator deals with issues like whether to use regular or wide instructions,
-what the actual instruction codes are, what the actual offsets for branches are etc.,
-so the compiler can abstract from these details. One can almost think of this as producing
-assembly.
-
-The trickiest part of the byte code compiler is deciding when to pop the result of an expression. Subexpressions leave their result on the operand stack, but top level expressions need not, since the result is not used. Furthermore, the VM does not clean up the operand stack upon return from a method, it seeems, so we are obligated to leave an empty operand stack on method exit.
-
-There would appear to be a space-time tradeoff - we can spend cycles popping results, or we can allocate a larger operand stack. But since we always need to clean it up, the time is always lost so we should optimize for space.
-
-In straight line code, the situation is simple: keep track of the depth of the stack, and pop it to zero at the end of a statement. However, once we have conditional branches, we need to ensure that the last statement in a branch leaves its result, because it is in fact a subexpression.
-
-However, this is not true in case of loops!
-
-We do not need to retain the result of the last statement of a non-inlined closure. This is its value, but the rewriter  already takes care of this by inserting a local return.
-
-The compiler tracks whether we are at the start of a statement or not using the boolean slot statementStarting. When traversing nodes that may have subexpressions, the current value of statementStarting is always saved before traversing subexpressions, and restored afterwards. The convention is to store the current value of statementStarting into a local named shouldPop (since we should pop the operand stack if we are at the start of a statement, i.e., the expression is a top level one and its value will not be used).
-
-The value of shouldPop is used when there is a choice between generating a popping or non-popping version of a bytecode. It is not, however, used to pop the results of individual subexpressions. Rather than clutter the logic with tests of shouldPop (or statementStarting) everywhere, we ensure that the method statementEnd is called at the end of each statement. It pops the stack as needed. Since only top level expressions will be popped, this does not change the maximal operand stack size; it only centralizes the handling.
-
-The statementEnd method is called by CodeBodyAST, which traverses the statement lists. Also, when traversing a CodeBodyAST, statementStarting is set to true before each statement is handled - except for the last statment, whose result we may need as noted above.
-
-statmentEnd needs to know how many pops to perform. Whenever we start a new CodeBodyAST, we must remember the depth of the operand stack at that time (stored in statementBaselineStackDepth). At the end of each statement, we want to pop the stack down to that depth. This complication could be avoided if we chose to have every expression consider whether it was top level or not.
-
-Keeping track of operand stack depth is not as simple as it seems.
-Closure code appears inline (regardless of whether execution is inlined!). Code in a non-inlined closure starts executing with an empty operand stack, but the depth of the method must be sufficient for the block.
-
-To complicate matters further, the actual size of the activation is simply the sum of the number of parameters, number of locals and maximal operand stack size.
-
-We must ensure sufficient space for any given closure defined in the method. The space required for a closure is the sum of its arity, the number of values copied into it, and its maximal operand stack size. Because the closure must explicitly initialize its locals to nil on startup, its operand stack will include sufficient space for its temporaries.
-
-Ideally, we'd track the operand stack depth for the method and for each closure within it separately. Though it seems that the actual required depth would be the maximum of all these, that is simplistic.
-
-We really need to compute the required context size which is the maximum of:
-
-#method formals + #method locals + method operand stack size
-
-#closure formals + #closure copy downs + closure operand stack size
-
-assuming that the locals of the closure are accounted for in the stack size.
-
-Then, the actual operand stack size we specify for the method is
-
-context size - #method formals - #method locals
-
-We don't do this yet.  What we do instead is often suboptimal, but sometimes insufficient. We compute the cumulative maximum operand stack size for all code in the method, including closures. The idea was that this would be conservative and simple, but in fact it may fail if a closure has a large number of arguments and copy-downs, and the actual operand stack usage is small."
-| 
-  cgen <CodeGenerator> = CodeGenerator new.
-  storeVisitor <StoreVisitor> = StoreVisitor generator: cgen.  
-  popAndStoreVisitor <PopAndStoreVisitor> = PopAndStoreVisitor generator: cgen. 
-  debugInfo <DebugInfo> = DebugInfo new.
-  result <LowLevelMethodMirror>
-  statementStarting ::= true.
-  statementBaselineStackDepth <Integer> = 0.
-  maxClosureContextSize <Integer> ::= 0.
-  scopeStack <OrderedCollection[Scope]> = OrderedCollection new.
-
-  offsetStack <OrderedCollection[Integer]> = OrderedCollection new. "see codeBodyNode:"
-  contextDepth <Integer> ::= 0.
-|
-
-)
-
-(
-
-
-
-class CodeGenerator = (
-"Handles actual byte code generation.  Defines slots corresponding to constants in the Squeak/Newspeak instruction set, as well as the ste of special selectors that are handled magically by the Squeak VM (per the Smalltalk blue book)."
-
-| 
-code = LowLevelMethodMirror new .
-
-optimize ::= true.
-longJumps ::= false. 
-shortJumpFailureBlock ::= [].
-
-noOfTemps ::= 1. "temp0 always allocated"
-stackMax ::= 0.
-currentStackDepth ::= 0.
-
-"Constants for the instruction set"
- 
-"stack manipulation instructions"
-  pushInstVar = 0.
-  pushTemp = 16.
-  pushLiteralConst = 32.
-  pushLiteralVar = 64.
-  storeAndPopInstVar = 96.
-  storeAndPopTemp = 104.
-  pushReceiver = 112.
-  pushTrue = 113.
-  pushFalse = 114.
-  pushNil = 115.
-  pushNibble = 116. 
-  pushZero = 117.
-  pushOne = 118.
-  pushTwo= 119.
-
-  extendedPush = 128.
-  extendedStore = 129.
-  extendedStoreAndPop = 130.
-  wide = 132.
-  store = 160.
-  storeAndPop = 192.
-  push = 64.
-  pop = 135.
-  pushLit = 96.
-  dupTos = 136.
-  pushActiveContext = 137.
-  
-  pushImplicitReceiver = 127. "for now"
-  dynamicSuperSend = 126. 
-" like extended super send, but find superclass dynamically"
-  outerSend = 139. "Explicit outer send"
-
-" send instructions"
-  extendedSend = 131.
-  extendedSendWide = 132.
-  superSend = 133.
-  extendedSuperSend = 134.
-  specialSend = 176.
-  sendBlockCopy = 200.
-  basicSend = 208.
-
-"closure instructions"
-  pushArray = 138.
-  pushRemoteTemp = 140.
-  storeRemoteTemp = 141.
-  storeAndPopRemoteTemp = 142.
-  pushClosure = 143.
-
-"jump instructions"
-  jump = 144.
-  popAndJumpOnFalse = 152.
-  longJump = 160.
-  popAndLongJumpOnTrue = 168.
-  popAndLongJumpOnFalse = 172.
-  maxJump = 1023.
-  minJump = -1024.
-  bits9to11 = 16r700.
-
-"return instructions"
-  returnReceiver = 120. 
-  returnTrue = 121.
-  returnFalse = 122.
-  returnNil = 123.
-  return = 124.
-  blockReturn = 125.
-
-  slotsPerMethod = 64.
-  specialSelectors = Dictionary new.
-|
-
-
-{#+. #-. #<. #>. #<=. #>=. #=. #~=. #*. #/. #\\. #@. 
-#bitShift:. #//. #bitAnd:. #bitOr:. 
-#at:. #at:put:. #size. #next. #nextPut:. #atEnd.
-#==.
-#class. #blockCopy:. #value. #value:. #do:. #new. #new:. #x. #y}
-with: (specialSend to: basicSend -1) do:[:sel <Symbol> :i <Integer> |
-  specialSelectors at: sel put: i.
-  ].
-"specialSelectors removeKey: blockCopy:"
-)
-
-('as yet unclassified'
-
-argCount: n = (
-
-
-
-blockCopy = ( 
    decrementStackDepthBy: 1.
    code byte: sendBlockCopy
-
-
-
-decrementStackDepthBy: n = (
-
-
-
-ensureBaselineStackDepth = (
-
-
-
-ensureEmptyStack = (
-
-
-
-incrementStackDepthBy: n = (
-
-
-
-jumpBy: offset <Integer>  = (
      adjust:: "((offset bitAnd: bits9to11) + 4) \\ 7" offset // 256 + 4 .
-
-
-
-literals: ls
 = (
    code literals: ls.
-
-
-
-maxLocals ^ <Integer> = (
-
-
-
-maxLocals: n <Integer> = (
-
-
-
-methodName: n <Symbol> = (
-
-
-
-normalSend: sel <Symbol> noOfArgs: n <Byte> 
 = (
    | op <Byte> data <Byte> selIndex <Byte>|
    decrementStackDepthBy: n.
    (isSpecialSelector: sel) ifTrue:[^sendSpecial: sel].
    selIndex:: literalIndexFor: sel.
    assert: [n >= 0 and:[n < 256]] message: 'n must be between 0 and 255'.
    assert:[selIndex >= 0 and: [selIndex < 256]] 
    (selIndex > 15 or:[n > 2])  ifTrue:[ "need an extended send"
       (n  < 8 and:[selIndex < 32]) ifTrue:[
          op:: extendedSend. "131"
          data:: n*32 + selIndex. "replace multiplication by bitshift?"
          code byte: op; byte: data.
          ^self
          ].
       op:: extendedSendWide. "132"
       code byte: op; byte: n; byte: selIndex.
    ].
    op:: basicSend. "208"
    code byte:  n*16 + op + selIndex."replace multiplication by bitshift?"
-
-
-
-patchJump: index <Integer> with: targetData <Integer> = (
-
-
-
-patchPopAndJump: index <Integer> with: targetData <Integer> = (
-
-
-
-popAndJumpOn: bool <Boolean> by: offset <Integer>  = (
-
-
-
-pushClosureOfArity: n <Integer> copying: m <Integer> length: s <Integer>  = (
-
-
-
-pushEmptyArray: n <Integer> = (
-
-
-
-pushExplicitOuterReceiver: n <Number> = (
   	incrementStackDepthBy: 1.
   	code byte: outerSend; "139"
   		  byte: (literalIndexFor: n).	
-
-
-
-pushFullArray: n <Integer> = (
-
-
-
-pushImplicitRcvr: sel <Symbol>  = (
    | selIndex <Byte> |
    selIndex:: literalIndexFor: sel.
    assert:[selIndex >= 0 and: [selIndex < 256]]
   incrementStackDepthBy: 1.
    code byte: pushImplicitReceiver; "127"
            byte: selIndex.
-
-
-
-pushLiteralIndex: litIndex <Integer> = (
  assert:[litIndex < 256 and:[litIndex >= 0]].
  incrementStackDepthBy: 1.
  litIndex < 32 ifTrue:[
  litIndex < 64 ifTrue:[
  code byte: wide; byte: pushLit; byte:  litIndex.
-
-
-
-pushMinusOneObj = (
-
-
-
-pushMixinClass = (
-
-
-
-pushOneObj = (
-
-
-
-pushRemoteTemporary: n <Integer> at: j <Integer>
 = (
      incrementStackDepthBy: 1.
-
-
-
-pushThisContext = (
      incrementStackDepthBy: 1.
-
-
-
-pushTwoObj = (
-
-
-
-pushZeroObj = (
-
-
-
-returnBoolFalse = (
    code byte: returnFalse.
-
-
-
-returnBoolTrue = (
    code byte: returnTrue.
-
-
-
-returnFromBlock = (
    code byte: blockReturn.
    decrementStackDepthBy: 1.
-
-
-
-returnNilObj = (
    code byte: returnNil.
-
-
-
-returnObject = (
    code byte: return.
    decrementStackDepthBy: 1.
-
-
-
-returnSelf = (
    code byte: returnReceiver.
-
-
-
-storeAndPopRemoteTemporary: n <Integer> at: j <Integer>
 = (
-
-
-
-storeInstanceVariable: offset <Integer>
 = (
     	assert:[offset >= 0 and:[offset < 254]]
     	offset <  64 ifTrue:[code byte: extendedStore; byte: offset. ^self]. "129; offset"
-
-
-
-storeRemoteTemporary: n <Integer> at: j <Integer>
 = (
-
-
-
-storeTemporary: n <Integer>
 = (
-
-
-
-'Unclassified'
-
-bci
 = (
    "Answers the current bci."
    ^ code size
-
-
-
-close ^ <LowLevelMethodMirror>
 = (
    "To be called at the end of code generation."
    code maxStack: (stackMax + code argCount + code maxLocals  max: maxClosureContextSize). "; klass:: methodsEnclosingMixin  implementationMirror implementationClass " 
    ^code
-
-
-
-dup = (
  code byte: dupTos. "136"
  incrementStackDepthBy: 1.
-
-
-
-isSpecialSelector: sel <Symbol> ^ <Boolean> = (
  ^specialSelectors includesKey: sel
-
-
-
-label: pos
 = (
-
-
-
-length: block
 = (
-
-
-
-literalIndexFor: s <Symbol> ^ <Integer> = (
  "Look the symbol up in the literal table and get its index"
  ^literalTable at: s
-
-
-
-or
 = (
    "Answers fixup address."
    longJumps
        ifTrue: [code byte: (HCodeTable at: #orL) word: 0]
        ifFalse: [code byte: (HCodeTable at: #orS) byte: 0].
    ^ code size
-
-
-
-popTos
 = (
    code byte: pop.
    decrementStackDepthBy: 1.
-
-
-
-pushANibble: n <Integer> = (
  assert:[n > -2 and:[n <3]] message: 'nibble must be between -2 and 5'.
  code byte: pushNibble + n + 1.
   incrementStackDepthBy: 1.
-
-
-
-pushBoolFalse = (
    code byte: pushFalse.
   incrementStackDepthBy: 1.
-
-
-
-pushBoolTrue = (
    code byte: pushTrue.
   incrementStackDepthBy: 1.
-
-
-
-pushGlobalVar: assoc
 = (
    code byte: (HCodeTable at: #pushGlobalVar) oop: assoc
-
-
-
-pushInstanceVariable: n <Integer>
 = (
       incrementStackDepthBy: 1.
       n < 8 ifTrue:[code byte: pushInstVar + n. ^self].
-
-
-
-pushLiteral: lit <Symbol | Character | Number> = (
-
-
-
-pushNilObj = (
    code byte: pushNil.
    incrementStackDepthBy: 1.
-
-
-
-pushSelf
 = (
-
-
-
-pushTemporary: n
 = (
      incrementStackDepthBy: 1.
-
-
-
-pushTos
 = (
    code pushTos.
    incrementStackDepthBy: 1.
-
-
-
-sendSpecial: sel <Symbol> = (
   code byte: (specialSelectors at: sel).
-
-
-
-storeAndPopGlobalVar: assoc
 = (
    code byte: (HCodeTable at: #storeGlobalVarPop) oop: assoc
-
-
-
-storeAndPopInstanceVariable: offset <Integer>
 = (
   assert:[offset >= 0 and:[offset < 254]]. 
   decrementStackDepthBy: 1.
   offset <  8 ifTrue:[code byte: storeAndPopInstVar + offset. ^self]. "96 + offset"
   offset <  64 ifTrue:[code byte: extendedStoreAndPop; byte: offset. ^self].
   code byte: wide; byte: storeAndPop; byte: offset. "132; 192; offset"
-
-
-
-storeAndPopTemporary: n <Integer>
 = (
-
-
-
-superSend: sel <Symbol>  noOfArgs: n <Integer> = (
    | selIndex <Byte> |
    selIndex:: literalIndexFor: sel.
    assert: [n >= 0 and:[n < 256]] 
    assert:[selIndex >= 0 and: [selIndex < 256]]
   decrementStackDepthBy: n.
    code byte: dynamicSuperSend; "126"
            byte: n; byte: selIndex.
-
-
-
-)
-
-
-
-class PopAndStoreVisitor  generator: gen = StoreVisitor generator: gen (
-"A visitor for issuing pop-and-store instructions. In some situations, one does not want to keep the result of a store on the operand stack, and this visitor is used in those cases. This allows us to take advantage o fthe dedicated instructions for op and store, rather than doing a store and then an explicit pop"
-
-)
-
-('as yet unclassified'
-
-instVarNode: node <InstVarAST> = (
-
-
-
-temporaryNode: node <TemporaryVariableAST> = (
-
-
-
-)
-
-
-
-class StoreVisitor generator: gen = (
-| cgen = gen. |
-)
-
-('node traversal'
-
-instVarNode: node <InstVarAST> = (
-
-
-
-parameterNode: node <ParameterAST>
 = (
-
-
-
-receiverNode: node <ReceiverAST>
 = (
-
-
-
-superVarNode: node <SuperVarAST>
 = (
-
-
-
-temporaryNode: node <TemporaryVariableAST> = (
-
-
-
-)
-
-
-
-class DebugMapper forContext: ctxt usingDebugInfo: dbgInfo = (
-""
-|
-	context <MethodContext> = ctxt.
-	debugInfo <DebugInfo> = dbgInfo.
-	myDepth <Integer> = self depthOfContext: ctxt.
-|
-)
-
-('as yet unclassified'
-
-astForContextAtDepth: targetDepth <Integer> ^<AST> = (
-
-
-
-contextAtDepth: targetDepth <Integer> ^<MethodContext> = (
-
-
-
-depthOfContext: ctxt <MethodContext> ^<Integer>= (
-
-
-
-getValueOf: varName <Symbol> ^<Object> = (
-
-
-
-getterAstFor: varName <Symbol> ^<SendAST> = (
-
-
-
-localNames = (
-
-
-
-mostLocalInfoFor: varName <Symbol> ^<LocalVarDebugInfo> = (
-
-
-
-pc = (
-
-
-
-setterAstFor: varName <Symbol> putting: newVal <AST> ^<SendAST> = (
-
-
-
-)
-
-
-
-class DebugInfo = (
-"Debugger information."
-|
-	private sourceMapping <MutableMap[Integer, Interval]> = Dictionary new.
-	localVariables <MutableList[LocalVariableDebugInfo]> = OrderedCollection new.
-|
-)
-
-('as yet unclassified'
-
-addInfoForLocal: varInfo <SemanticVarDecl> = (
-
-
-
-addInfoForRemote: varInfo <SemanticVarDecl> in: remoteVarInfo <SemanticVarDecl> = (
-
-
-
-mapPC: pc <Integer> to: src <interval> = (
-
-
-
-mapperForContext: ctxt = (
-
-
-
-sourceMap ^ <SortedList[Association[Integer, Interval]]> = (
-
-
-
-)
-
-
-
-class LocalVariableDebugInfo = (
-"Debugger information for a local."
-|
-      name <Symbol>
-	validPCRange <Interval>
-	zeroOriginOffset <Integer> "in remoteVector if not nil, otherwise in context"
-	remoteVector <Symbol | nil>
-	contextDepth <Integer> "0 = method, 1 = closure, 2 = nested closure, ... "
-	
-|
-)
-
-('as yet unclassified'
-
-isSynthetic ^<Boolean> = (
-
-
-
-)'as yet unclassified'
-
-addDebugInfo: sourceInterval <Interval> = (
-
-
-
-addLocalVar: v <VarDeclAST> = (
-
-
-
-addVar: v <VarDeclAST> at: i <Integer> = (
-
-
-
-arrayNode: node <ArrayAST> = (
-
-
-
-blockLocalReturnNode: node <BlockLocalReturnAST> = (
  shouldPop:: statementStarting.
   statementStarting:: false.
   node expr apply: self.
   cgen returnFromBlock.	
   statementStarting:: shouldPop.
-
-
-
-boolNode: node = (
  assert: [ node apply: rewriter BoolVisitor new] message: 'Boolean node expected'.
  node val ifTrue:[cgen pushBoolTrue]
               ifFalse:[cgen pushBoolFalse].
-
-
-
-cascadedSendNode: node <CascadedSendAST> = (
   shouldPop:: statementStarting.
   statementStarting:: false.
   isSuperSend:: false "node recv apply: SuperVarVisitor new".
   node recv apply: self.
   isSuperSend ifTrue:[
       cascadeSuper: node prevSend depth: 1.
       generateSuperSend: node.
      ]
      ifFalse:[
         cascadeNormal: node prevSend depth:1.
         cgen popTos.
         node msg apply: self.
         generateSend: node.
      ].
   statementStarting:: shouldPop.
-
-
-
-closureNode: node <ClosureAST> = (
-
-
-
-contextNode: node = (
  assert: [ node apply: rewriter ContextVisitor new] message: 'Context expected'.
  cgen pushThisContext.
-
-
-
-currentMethod ^ <SemanticMethod> = (
-
-
-
-currentScope ^ <Scope> = (
-
-
-
-doReturnBool: b <Boolean> = (
  b ifTrue:[cgen returnBoolTrue] ifFalse:[cgen returnBoolFalse].
-
-
-
-doReturnNil = (
  cgen returnNilObj.
-
-
-
-doReturnSelf = (
  cgen returnSelf.
-
-
-
-explicitOuterReceiverNode: aNode <ExplicitOuterReceiverAST> = (
-
-
-
-extractParam: p <ParameterAST> = (
-
-
-
-generateSuperSend: node <SendAST> = (
  node msg apply: self.
  cgen superSend: node msg sel noOfArgs: node msg args size.
  addDebugInfo:  (node start to: node msg end).
-
-
-
-implicitSendNode: node <ImplicitRcvrSendNode> = (
  shouldPop:: statementStarting.
  statementStarting:: false.
  cgen pushImplicitRcvr: node msg sel.
  node msg apply: self.
  cgen normalSend: node msg sel noOfArgs: node msg args size.
  addDebugInfo:  (node msg start to: node msg end).
  statementStarting:: shouldPop.
-
-
-
-isRemote: node ^ <Boolean> = (
-
-
-
-literalArray ^  <Array[Character | Number | String | Symbol]> = (
-
-
-
-mixinClassNode: node  = (
-
-
-
-nextOffset = (
-
-
-
-nilNode: node = (
  assert: [ node apply: rewriter NilVisitor new] message: 'Nil node expected'.
  cgen pushNilObj.
-
-
-
-numberNode: node <NumberAST>  = (
-
-
-
-pc = (
-
-
-
-popAndStoreInto: v <VarDeclAST> = (
   v apply: popAndStoreVisitor. 
-
-
-
-popOffsetCounter = (
-
-
-
-popScope ^ <Scope> = (
  ^scopeStack removeLast
-
-
-
-processLiteralMessagesOf: node <MethodAST> = (
-
-
-
-pushOffsetCounter = (
-
-
-
-pushScope: s <Scope>= (
 scopeStack addLast: s
-
-
-
-returnStatNode: node <ReturnStatAST> = (
   assert:[node isReturnStatNode] message: 'Return node expected'.
  shouldPop:: statementStarting.
   (node expr apply: rewriter ReceiverVisitor new) ifTrue:[^doReturnSelf].
   (node expr apply: rewriter BoolVisitor new) ifTrue:[^doReturnBool: node expr val].
   (node expr apply: rewriter NilVisitor new) ifTrue:[^doReturnNil].
   statementStarting:: false.
   node expr apply: self.
   doReturn.
   statementStarting:: shouldPop.
-
-
-
-setup = (
  	storeVisitor:: StoreVisitor generator: cgen.  
  	debugInfo:: DebugInfo new.
-
-
-
-slotsPerMethod ^ <Integer> = (
-
-
-
-statementEnd = (
-
-
-
-stringNode: node <StringAST>  = (
-
-
-
-symbolNode: node <SymbolAST>  = (
-
-
-
-'node traversal'
-
-assignmentNode: node <AssignmentAST> = (
      shouldPop ifTrue:[popAndStoreInto: node var] 
-
-
-
-charNode: node <CharAST> = (
  "add literal char to literal table"
  cgen pushLiteral: node val
-
-
-
-codeBodyNode: node <CodeBodyAST> = (
   stmtSize:: node statements size.
   shouldPop:: statementStarting.
   i:: 1.
   depth:: statementBaselineStackDepth.
   statementBaselineStackDepth::  cgen currentStackDepth.
   node statements do:[:s | 
  validPCRange:: startPC to: pc.
  localVariableDebugInfos do: [:each | each validPCRange: validPCRange].
  statementBaselineStackDepth::  depth.
-
-
-
-ifNode: node <IfAST> = (
  shouldPop:: statementStarting.
  statementStarting:: false. 
  node cond apply: self.
  cgen popAndJumpOn: node ifTrue not by: 0. "jump to else (but needs patching)"
  statementStarting:: shouldPop.
  ifPos:: cgen bci. "remember patch address"
  depth:: cgen currentStackDepth.
  assert:[node then isBlockNode and:[node then parameters isEmpty]]
  pushScope:: scopeMap at: node then body.
  node then body apply: self.
  thenDepth: cgen currentStackDepth.
  popScope.
  node else isNil ifTrue:[endThen:: cgen bci.]
-
-
-
-instVarNode: node
 = (
-
-
-
-loopNode: node <LoopAST> = (
  shouldPop:: statementStarting.
  statementStarting:: false. 
  node body isNil ifFalse:[pushScope:: scopeMap at: node body].
  depth:: cgen currentStackDepth.
  node prologue apply: self.
  [cgen currentStackDepth > depth] whileTrue:[cgen popTos].
 "Ensure prologue maintains stack depth to prevent overflowing it during say nested loops."
  topOfLoop:: cgen bci + 1.
  skope:: scopeMap at: node cond ifAbsent:[nil].
  skope isNil ifFalse:[pushScope:: skope]. 
  node cond  apply: self. 
  skope isNil ifFalse:[popScope].
  cgen popAndJumpOn: node isWhileTrue not by: 0. 
  statementStarting:: shouldPop.
  whilePos:: cgen bci. "remember patch address"
  node body isNil ifFalse:[
 "Ensure loop body maintains stack depth to prevent overflowing it during loop execution."
  cgen jumpBy: topOfLoop - cgen bci - 3. "jump to top of loop"
  cgen patchPopAndJump: whilePos with: cgen bci - whilePos.
 "patch the jump after the test so it comes to end of the then block"
  cgen pushNilObj. "result of loop message"
  statementStarting:: shouldPop.
-
-
-
-messageNode: m <MessageAST> = (
  m args do:[:a <ExpressionAST> | a apply: self].
-
-
-
-messagePatternNode: node <MessagePatternAST> = (
  node parameters do:[:p | addLocalVar: p]
-
-
-
-methodNode: node <MethodAST> = (
   setup.
   pushScope: (scopeMap at: node).  pushOffsetCounter.
   currentScope at: #'`currentMethod' put: (SemanticMethod decl: node).
   argC:: node pattern parameters size.
   cgen maxLocals: 0.
  " node pattern apply: self. Parems will be added by the code body"
   cgen methodName: node pattern selector; argCount: argC; literals: literalArray.
   node body apply: self.
   cgen code debugInfo: debugInfo. "set debug info"
   processLiteralMessagesOf: node.
   currentMethod frameSize: cgen maxLocals.
   popScope. popOffsetCounter.
   result:: cgen close.
-
-
-
-normalSendNode: node <NormalSendAST> = (
   assert: [ node isNormalSendNode] message: 'NormalSendNode expected'.
   shouldPop:: statementStarting.
   statementStarting:: false.
   node recv apply: self.
   node msg apply: self.
   generateSend: node.
   statementStarting:: shouldPop.
-
-
-
-parameterNode: node <ParameterAST> = (
-
-
-
-receiverNode: node = (
  assert: [ node apply: rewriter ReceiverVisitor new] message: 'Receiver node expected'.
  cgen pushSelf.
-
-
-
-returnInstVarMethodNode: node <ReturnInstVarMethodAST>
  ^ <LowLevelMethodMirror> = (
  "create an empty compiled method with appropriate flags"
   result:: LowLevelMethodMirror new selector: node selector; 
   ^result
-
-
-
-returnSelfMethodNode: node <ReturnSelfMethodAST> ^ <LowLevelMethodMirror>  = (
  "create an empty compiled method with appropriate flags"
   result:: LowLevelMethodMirror new selector: node selector; 
                                                         returnOnlySelf: currentMethodSource.
   ^result
-
-
-
-superSendNode: node <SuperSendNode> = (
  shouldPop:: statementStarting.
  cgen pushSelf.
  generateSuperSend: node.
  statementStarting:: shouldPop.
-
-
-
-superVarNode: node <SuperVarNode>  = (
  cgen pushSelf.
-
-
-
-temporaryNode: node <TemporaryVariableAST> = (
-
-
-
-'private'
-
-cascadeNormal: node <SendAST> depth: n <Integer> = (
  node isCascadedSendNode 
     ifFalse:[cgen dup"n timesRepeat:[cgen dup]"]
     ifTrue:[cascadeNormal: node prevSend depth: n + 1].
   node msg apply: self.
   generateSend: node.
   cgen popTos.
   cgen dup.
-
-
-
-cascadeSuper: node <SendAST> depth: n <Integer> = (
  node isCascadedSendNode 
     ifFalse:[n timesRepeat:[cgen dup]]
     ifTrue:[cascadeSuper: node prevSend depth: n + 1].
   generateSuperSend: node.
   cgen popTos.
-
-
-
-currentMethodSource ^ <String> = (
  ^outer Compiler input contents
-
-
-
-doReturn = (
-
-
-
-generateSend: node <SendNode>  = (
   cgen normalSend: node msg sel noOfArgs: node msg args size.
    addDebugInfo:  (node start to: node msg end).
-
-
-
-indexOfVar: v <VarDeclAST> ^ <Integer> = (
   ^(currentScope at: v name asSymbol) offset
-
-
-
-storeInto: v <VarDeclAST> = (
   v apply: storeVisitor. 
-
-
-
-vectorOf: v <VarDeclAST> ^ <VarDelcAST> = (
   ^(currentScope at: v name asSymbol) remoteVector
-
-
-
-)
-
-
-
-class Rewriter = ASTTool (
-"A visitor that rewrites the AST into a form more suitable for compilation to the Squeak VM.
-
-It may be possible to combine the pass that constructs the scopes with the rewriting pass, but this may be messy once we start inlining blocks etc."
-	| 
-	scope <Scope> 
-	scopeStack <OrderedCollection[Scope]> = OrderedCollection new.
-	|
-)
-
-(
-
-
-
-class BlockLocalReturnAST expression: x start: s end: e =  AST (
-"This class represents a 'local return' (LR) -  a return from a block to its caller, as opposed to the caller of its enclosing method (a 'non-local return' or NLR).
-
-An actual return statement in a block means an NLR; an LR is implicit in the source language, and occurs on the last statement of the block, unless that statement is a true return (NLR).  However, the back end of the compiler requires that this information be represented explicitly. This node does that."
-|
- expr <ExpressionAST> = x.
-|
-start: s. end: e.
-)
-
-('as yet unclassified'
-
-apply: aTool <ASTTool>  = (
-
-
-
-)
-
-
-
-class LoopAST = AST (
-"This node represents a while loop, and its various routines act as constructors that map from various looping constructs into a while loop. In some cases (like whileTrue:) this is trivial, in others it is a bit more involved.
-
-The general form of the loop is:
-
-prologue;
-while (cond = whileTrue) { body}
-
-Ergo, prologue represents some code that sets up the loop (e.g., the initialization of the loop variable when encoding a for loop into a while loop);
-whileTrue is true if the loop continues as long as the test condition holds, and false if the loop runs as long as the condition does not hold;
-cond is the aforementiond test condition; body is the body of the loop."
-
-| 
-isWhileTrue <Boolean> 
-prologue <CodeBodyAST> ::= 
-	CodeBodyAST new 
-			parameters: OrderedCollection new;
-			temporaries: OrderedCollection new;
-			statements: OrderedCollection new.
-cond <CodeBodyAST> 
-body <CodeBodyAST>  |
-)
-
-('as yet unclassified'
-
-isExpressionNode ^ <boolean> = (
-
-
-
-'public access'
-
-apply: aTool <ASTTool>
 = (
    ^aTool loopNode: self
-
-
-
-do: n <Integer> timesRepeat: block <BlockAST>
 = (
-
-
-
-from: first <AST> to: last <AST> by: step <AST> do: block <BlockAST>
 = (
-
-
-
-from: first <AST> to: last <AST> do: block <BlockAST>
 = (
-
-
-
-repeat: block <BlockAST>
 = (
    assert: [block isBlockNode].
    cond:: block body.
    cond statements add: (BoolAST withValue: true start: cond end end: cond end).
    isWhileTrue:: true.
    body:: nil
-
-
-
-while: v <Boolean> do: b <BlockAST>
 = (
    assert: [b isBlockNode].
    cond:: b body.
    isWhileTrue:: v.
    body:: nil
-
-
-
-while: b1 <BlockAST>  is: v <Boolean> do: b2 <BlockAST>
 = (
    assert: [b1 isBlockNode].
    assert: [b2 isBlockNode].
    cond:: b1 body.
    isWhileTrue:: v.
    body:: b2 body
-
-
-
-)
-
-
-
-class ClosureAST for: block withCopiedValues: cv = BlockAST (
-|
-	copiedValues = cv.
-	pushNilCount ::= 0.
-|
-	body: block body.
-)
-
-('as yet unclassified'
-
-apply: aTool = (
-
-
-
-)
-
-
-
-class ImplicitRecvrVisitor = FalseVisitor ()
-
-('as yet unclassified'
-
-implicitSendNode: aNode <ImplicitRcvrSendAST> ^ <Boolean> = (
-
-
-
-)
-
-
-
-class ImplicitRecvrSendAST send: aMsg <MessageAST> = SendAST send: aMsg (
-"
-Represent a send of a message with an implicit receiver (aka a here send).
-"
-)
-
-('as yet unclassified'
-
-apply: aTool <ASTTool> ^ <Self> = (
-
-
-
-isExpressionNode ^ <boolean> = (
-
-
-
-recv ^ <VarDeclAST> = (
  ^ assert:[false] message: 'There is no receiver node. It is implicit'
-
-
-
-)
-
-
-
-class NilVisitor = FalseVisitor ()
-
-('as yet unclassified'
-
-nilNode: node = (^true)
-
-
-
-)
-
-
-
-class SuperSendAST send: aMsg <MessageAST> = SendAST send: aMsg (
-"This code is currently unused.  
-Unlike Smalltalk, super calls in Newspeak cannot be statically bound.
-Hence, we cannot use the Squeak VM's  super send byte codes. Currently, super sends are rewritten into a complex call structure by the rewriter, to ensure the correct binding of super.
-
-When the Newspeak VM is modified to support dynamic binding of super sends, we will probably use this node and allied code,  which can easily be processed by the byte code compiler and code generator."
-)
-
-('as yet unclassified'
-
-isExpressionNode ^ <boolean> = (
-
-
-
-'Unclassified'
-
-apply: aTool <ASTTool> ^ <Self> = (
-
-
-
-recv ^ <SuperVarAST> = (
  ^SuperVarAST new
-
-
-
-)
-
-
-
-class TemporaryAST name: n type: t = VarDeclAST name: n type: t (
-""
-)
-
-('as yet unclassified'
-
-isTemporaryAST ^ <Boolean> = (
-
-
-
-variableClass ^ <TemporaryVariableAST class> = (
-
-
-
-'Unclassified'
-
-apply: aTool <ASTTool > ^ <Self> = (
-
-
-
-printOn: strm <CharOutputStream>
 = (
-
-
-
-)
-
-
-
-class SuperSendVisitor = FalseVisitor ()
-
-('node traversal'
-
-superSendNode: node <SuperSendAST> = (
      ^true
   )
-
-
-
-)
-
-
-
-class ReturnInstVarMethodVisitor = FalseVisitor ()
-
-('node traversal'
-
-returnInstVarMethodNode: node = (^true)
-
-
-
-)
-
-
-
-class FalseVisitor = SuperFalseVisitor (
-"Extends the standard FalseVisitor with methods for dealing with the node types introduced by the rewriter.."
-)
-
-('as yet unclassified'
-
-arrayNode: n = (
-
-
-
-boolNode: node = (^false)
-
-
-
-closureNode: node = (
-
-
-
-contextNode: node = (^false)
-
-
-
-explicitOuterReceiverNode: aNode <ExplicitOuterRcvrAST> ^ <Boolean> = (
-
-
-
-ifNode: aNode <IfAST> ^ <Boolean> = (
-
-
-
-implicitSendNode: aNode <ImplicitRcvrSendAST> ^ <Boolean> = (
-
-
-
-loopNode: aNode <LoopAST> ^ <Boolean> = (
-
-
-
-nilNode: node = (^false)
-
-
-
-parameterNode: aNode <ParameterAST> ^ <Boolean> = (
-
-
-
-receiverNode: aNode <ReceiverAST> ^ <Boolean> = (
-
-
-
-returnInstVarMethodNode: aNode <ReturnInstVarMethodAST> ^ <Boolean> = (
-
-
-
-returnSelfMethodNode: aNode <ReturnSelfMethodAST> ^ <Boolean> = (
-
-
-
-superSendNode: aNode <SuperSendAST> ^ <Boolean> = (
-
-
-
-superVarNode: aNode <SuperVarAST> ^ <Boolean> = (
-
-
-
-temporaryNode: aNode <TemporaryVariableAST> ^ <Boolean> = (
-
-
-
-variableNode: aNode = (
-
-
-
-)
-
-
-
-class ContextAST = VariableAST (
-"Represents uses of thisContext. I expect these to be restricted in future versions. Currently, we use it for outer sends and super sends"
-
-)
-
-('as yet unclassified'
-
-apply: aTool <ASTTool > ^ <Self> = (
-
-
-
-name = (
-
-
-
-printOn: strm <CharOutputStream>
 = (
-
-
-
-)
-
-
-
-class ParameterAST name: n type: t = VarDeclAST name: n type: t (
-""
-)
-
-('as yet unclassified'
-
-variableClass ^ <ParameterVariableAST class> = (
-
-
-
-'Unclassified'
-
-apply: aTool <ASTTool > ^ <Self> = (
-
-
-
-printOn: strm <CharOutputStream>
 = (
-
-
-
-)
-
-
-
-class ReturnSelfMethodAST selector: s <Symbol> var: v <ReceiverAST>  =  AST (
-" This class represents a method with exactly one statement, which is a return
-  of the receiver.  Since Squeak, like Smalltalk-80, optimizes this case
-  by creating a special method without any bytecodes at all, we want to recognize it.
-  The rewriter will replace MethodASTs representing such methods with instances
-  of this class. The compiler will then process these nodes appropriately.
-  "
-  | var <ReceiverAST> = v.  selector <Symbol> = s.  |
-)
-
-('visiting'
-
-apply: tool <ASTTool> = (
  ^tool returnSelfMethodNode: self.
-
-
-
-)
-
-
-
-class SuperVarAST = VarDeclAST name: #super type: nil (
-""
-)
-
-('Unclassified'
-
-apply: aTool <ASTTool> ^ <Self> = (
-
-
-
-)
-
-
-
-class NeedsIndirectionFinder for: codebody = ASTTraverser (
-"This class will be renamed CodyBodyAnalyzer.
-
-A temp needs to be put in an indirection vector if
--it is written to in a nested closure
--it is written to its defining codebody after being read in a nested closure
-
-Inlined blocks do not count as nested closures, though any temps defined in an inlined block that are read before written need to be nil'ed to maintain the illusion that they are closures (to be implemented later).
-
-
-
-m = (
-| a b var |
-a:: [ var ].
-b:: [ var: 0 ].
-)"
-
-|
-	depth ::= 0.
-		
-	shadowing = Dictionary new.
-	needsIndirection ::= Set new.
-	hasNestedRead = Set new.
-	
-	includesSetterSend ::= false.
-|
-	codebody apply: self.
-	
-	needsIndirection:: needsIndirection select: [:ea |
-		in: codebody temporaries anySatisfy: [:t | ea = t name].
-	].
-)
-
-('as yet unclassified'
-
-codeBodyNode: node <CodeBodyAST> = (
-
-
-
-commonCodeBodyNode: node = (
-
-
-
-inlinedBlockNode: node <BlockAST> = (
-
-
-
-isShadowed: var <Symbol> ^<Boolean> = (
-
-
-
-normalSendNode: node <NormalSendAST> = (
-
-
-
-processHereSend: aMsg <MessageAST> = (
-
-
-
-processInlineableSend: node <NormalSendAST> = (
 
 
 
-
-
-
-returnStatNode: node <ReturnStatAST> = (
-
-
-
-setterSendNode: node <SetterSendAST> = (
-
-
-
-shadow: var <Symbol> = (
-
-
-
-variableNode: node <VariableAST> = (
-
-
-
-variableRead: var <Symbol> = (
-
-
-
-variableWrite: var <Symbol> = (
-
-
-
-)
-
-
-
-class ParameterVariableAST name: n start: s end: e = VariableAST (
-""
- name: n. start: s. end: e.
-)
-
-('as yet unclassified'
-
-apply: aTool <ASTTool > ^ <Self> = (
-
-
-
-)
-
-
-
-class BoolVisitor = FalseVisitor ()
-
-('as yet unclassified'
-
-boolNode: node = (^true)
-
-
-
-)
-
-
-
-class InstVarVisitor = FalseVisitor ()
-
-('node traversal'
-
-instVarNode: node = (^true)
-
-
-
-)
-
-
-
-class ReceiverVisitor = FalseVisitor ()
-
-('node traversal'
-
-receiverNode: node = (^true)
-
-
-
-)
-
-
-
-class TemporaryVariableAST name: n start: s end: e = VariableAST (
-"This node represents reference to a temporary variable."
- name: n.  start: s. end: e.
-)
-
-('as yet unclassified'
-
-apply: aTool <ASTTool > ^ <Self> = (
-
-
-
-)
-
-
-
-class ExplicitReceiverVisitor = FalseVisitor ()
-
-('as yet unclassified'
-
-explicitOuterReceiverNode: aNode <ExplicitOuterRcvrAST> ^ <Boolean> = (
-
-
-
-)
-
-
-
-class IfAST if: expr <ExpressionAST> is: val  <Boolean> then: block1 <BlockAST> else: block2 <BlockAST> = AST (
-""
-
-| 
-  cond <ExpressionAST> = expr.
-  ifTrue  <Boolean> = val.
-  then <BlockAST> = block1.
-  else <BlockAST> = block2.
-  |
-
-    assert: [expr isExpressionNode].
-    assert: [block1 isBlockNode].
-    assert: [block2 isNil or:[block2 isBlockNode]].
-
-)
-
-('as yet unclassified'
-
-isExpressionNode ^ <boolean> = (
-
-
-
-'visiting'
-
-apply: aTool <ASTTool>
 = (
    ^aTool ifNode: self
-
-
-
-) : (
-
-'as yet unclassified'
-
-emptyBlock = (
-
-
-
-'public access'
-
-if: expr <ExpressionAST> is: val <Boolean> then: block  <BlockAST> ^ <Instance>
 = (
  ^if: expr is: val then: block else: emptyBlock
-
-
-