This document analyzes the core classes and methods needed for implementing the three fundamental components of a self-hosting Smalltalk system: the testing framework, parser, and compiler.
TestCase
- setUp, tearDown
- assert:, deny:, assert:equals:
- should:raise:, shouldnt:raise:
- fail, fail:
- run, runCaseTestSuite
- addTest:, addTestsFor:
- run, tests
- name, name:TestResult
- initialize, runCount, errorCount, failureCount
- addError:, addFailure:, addPass:
- errors, failures, passed
- printOn:TestRunner
- run:, runSuite:
- report, printResultsException
- signal, signal:
- messageText, messageText:
Error (subclass of Exception)
- for test failures and errorsCollection protocol
- OrderedCollection (already have)
- do:, collect:, select: (for managing test lists)String
- =, printString, asString (for test names and messages)
- , (concatenation for building messages)Stream
- WriteStream for building output
- nextPutAll:, contentsParser
- parseMethod, parseClass
- parseExpression, parseStatement
- parseBlock, parseArray
- parseTemporaries, parseArgumentsToken
- type, value, position
- isIdentifier, isKeyword, isLiteral, etc.Scanner/Tokenizer
- nextToken, peekToken
- position, atEnd
- scanIdentifier, scanNumber, scanString, scanSymbolParseNode (AST nodes)
- MethodNode, ClassNode, BlockNode
- MessageNode, VariableNode, LiteralNode
- AssignmentNode, ReturnNodeSyntaxError
- position, message
- signal:at:String
- at:, size, copyFrom:to:
- first, last, isEmpty
- isDigit, isLetter, isAlphaNumeric
- asSymbol, asNumberCharacter
- isDigit, isLetter, isAlphaNumeric
- isSeparator, isUppercase, isLowercase
- =, asStringOrderedCollection
- add:, at:, size, do:
- first, last, isEmptyDictionary
- at:put:, at:ifAbsent:
- includesKey: (for keyword tables)Symbol
- = (for comparing selectors)
- asString, printStringCompiler
- compile:, compileMethod:in:
- compileBlock:, compileExpression:
- generateBytecode, optimizeCompiledMethod
- selector, bytecodes, literals
- numArgs, numTemps
- primitive, headerBytecodeGenerator
- pushLiteral:, pushTemp:, pushInstVar:
- storeTemp:, storeInstVar:
- send:numArgs:, return
- jump:, jumpIf:, jumpIfNot:MethodContext
- receiver, arguments, temporaries
- method, sender, pc
- push:, pop, topBytecode constants
- PUSH_LITERAL, PUSH_TEMP, etc.
- SEND_MESSAGE, RETURN, etc.Class
- name, superclass, methods
- addMethod:, lookupMethod:
- instanceVariableNames
- new (for creating instances)Method
- selector, bytecodes, literals
- numArgs, numTemps
- valueWithReceiver:arguments:Symbol
- = (for selector comparison)
- hash (for method lookup)Array
- at:, at:put:, size
- new: (for literals array)ByteArray
- at:, at:put:, size
- new: (for bytecode storage)Integer
- +, -, *, / (for bytecode generation)
- =, <, > (for comparisons)
- bitAnd:, bitOr:, bitShift: (for encoding)Block
- value, value:, value:value:
- numArgs, method- Exception (basic signal/handle)
- String (=, printString, ,)
- TestCase (assert:, deny:, setUp, tearDown)
- TestResult (basic counting)
- TestRunner (basic execution)
- Character (classification methods)
- String (at:, size, copyFrom:to:, character methods)
- Symbol (=, asString, creation)
- Scanner (basic tokenization)
- ParseNode hierarchy (basic AST)
- Parser (expression parsing first)
- Array (literals storage)
- ByteArray (bytecode storage)
- Integer (bytecode encoding)
- CompiledMethod (basic structure)
- BytecodeGenerator (basic opcodes)
- Compiler (expression compilation first)
- Needed by testing (test names, error messages)
- Needed by parser (source code manipulation)
- Needed by compiler (selector handling)
- Should be implemented first after basic testing
- Critical for method selectors
- Needed for variable names
- Required for proper identity semantics
- Must work correctly for compiler
- OrderedCollection (already have)
- Array (for literals and arguments)
- Dictionary (for method lookup, variable binding)
- Array is most critical for compiler
- Needed for testing (should:raise:, etc.)
- Needed for parser (error handling blocks)
- Needed for compiler (code generation blocks)
- Complex but essential for all three systems
Based on the dependency analysis, the implementation order should be:
- Basic Exception + String (enables testing)
- TestCase + TestRunner (enables TDD)
- Character + Symbol (enables parsing)
- Array + Integer (enables compilation)
- Block (enables advanced features in all systems)
This order ensures that each component has its dependencies available when needed, while maintaining the ability to test each component as it's developed.
- This analysis focuses on the minimal set of classes and methods needed for self-hosting
- Additional convenience methods can be added later once the core functionality is working
- The emphasis is on simplicity and correctness rather than completeness or performance
- Each class should be implemented with comprehensive test coverage before moving to the next