diff -rdu smalltalk-2.3.1/compiler/RBParseNodes.st smalltalk/compiler/RBParseNodes.st --- smalltalk-2.3.1/compiler/RBParseNodes.st 2006-02-05 12:41:19.000000000 -0600 +++ smalltalk/compiler/RBParseNodes.st 2006-12-30 22:07:01.000000000 -0600 @@ -953,8 +953,11 @@ ^self arguments copyWith: self body! primitiveSources + | offset | + offset := self start - 1. ^self tags - collect: [:each | self source copyFrom: each first to: each last]! + collect: [:each | self source copyFrom: each first - offset + to: each last - offset]! isBinary ^(self isUnary or: [self isKeyword]) not! @@ -991,10 +994,12 @@ source := anObject! start - ^1! + "Changed from the standard #start, which answers 1, because our + methods can easily start at different positions in the stream." + ^selectorParts first start! stop - ^source size! + ^self start + source size! tags ^tags isNil ifTrue: [#()] ifFalse: [tags]! diff -rdu smalltalk-2.3.1/compiler/RBParser.st smalltalk/compiler/RBParser.st --- smalltalk-2.3.1/compiler/RBParser.st 2006-02-05 12:41:19.000000000 -0600 +++ smalltalk/compiler/RBParser.st 2006-12-30 21:27:08.000000000 -0600 @@ -409,6 +409,11 @@ whileFalse: [self step]. (currentToken isBinary and: [currentToken value == #>]) ifFalse: [self parserError: '''>'' expected']. + + "The standard RBParser assumes that this method's token + start is always 1, borne out by RBMethodNode>>#start. + However, this is not the case here, because I can parse + fileIns properly." tags isNil ifTrue: [tags := OrderedCollection with: (start to: currentToken stop)] ifFalse: [tags add: (start to: currentToken stop)]. @@ -661,6 +666,7 @@ next | token | buffer reset. + "we've already read the first character of the token from stream" tokenStart := stream position. characterType == #eof ifTrue: [^RBToken start: tokenStart + 1]. "The EOF token should occur after the end of input" token := self scanToken. diff -rdu smalltalk-2.3.1/compiler/STCompiler.st smalltalk/compiler/STCompiler.st --- smalltalk-2.3.1/compiler/STCompiler.st 2006-02-05 12:41:19.000000000 -0600 +++ smalltalk/compiler/STCompiler.st 2006-12-30 21:59:25.000000000 -0600 @@ -55,8 +55,8 @@ ! ! STFakeCompiler subclass: #STCompiler instanceVariableNames: 'node destClass symTable parser bytecodes depth maxDepth isInsideBlock ' - classVariableNames: 'OneNode TrueNode FalseNode NilNode SuperVariable SelfVariable ThisContextVariable DoitToken' + classVariableNames: 'OneNode TrueNode FalseNode NilNode SuperVariable SelfVariable ThisContextVariable DoitToken AttributeCompilers' poolDictionaries: '' category: 'System-Compiler' ! @@ -101,7 +101,15 @@ NilNode := RBLiteralNode value: nil. SelfVariable := RBVariableNode named: 'self'. SuperVariable := RBVariableNode named: 'super'. - ThisContextVariable := RBVariableNode named: 'thisContext'! ! + ThisContextVariable := RBVariableNode named: 'thisContext'. + AttributeCompilers := IdentityDictionary new + at: #asyncCCall:args: + put: (self performWithBlock: #compileAsyncCCall:args:); + at: #cCall:returning:args: + put: (self performWithBlock: #compileCCall:returning:args:); + at: #primitive: + put: (self performWithBlock: #compilePrimitive:); + yourself! ! !STCompiler class methodsFor: 'evaluation'! @@ -155,6 +163,21 @@ yourself ! ! +!STCompiler class methodsFor: 'compiling method attributes'! + +attributeCompilers + "Answer an IdentityDictionary of method attribute message + selectors to two-argument blocks that can compile them given an + STCompiler and a Collection of argument RBTokens." + ^AttributeCompilers +! + +performWithBlock: selector + "Answer a block that will send selector to the first arg with the + second as arguments." + ^[:compiler :args | compiler perform: selector withArguments: args asArray] +! ! + !STCompiler methodsFor: 'private'! class: aBehavior parser: aParser @@ -426,6 +448,7 @@ depth := maxDepth := 0. self declareArgumentsAndTemporaries: node. + self compileMethodAttributes: node. self compileStatements: node body. self undeclareArgumentsAndTemporaries: node. symTable finish. @@ -934,4 +965,77 @@ arg: number ! ! +"--------------------------------------------------------------------" + +!STCompiler methodsFor: 'compiling method attributes'! + +compileMethodAttributes: methodNode + methodNode primitiveSources do: [:each | self compileAttribute: each] +! + +compileAttribute: aSourceString + "Compile attribute described by aSourceString." + | tokens selectorBuilder selector | + tokens := self scanAttribute: aSourceString. + tokens size even ifFalse: + [^self compileError: + 'method attributes must be given in keyword-value pairs']. + selectorBuilder := WriteStream on: String new. + + "check/build the selector" + 1 to: tokens size by: 2 do: [:keywordIdx | | keyword | + keyword := tokens at: keywordIdx. + keyword isKeyword ifFalse: + [^self compileError: 'keyword expected in method attribute']. + selectorBuilder nextPutAll: keyword value]. + + "select the compiling block and deliver the arguments" + selector := selectorBuilder contents asSymbol. + (self class attributeCompilers + at: selector + ifAbsent: [^self warnUnimplementedAttribute: selector]) + value: self + value: ((2 to: tokens size by: 2) collect: [:each | tokens at: each]) +! + +scanAttribute: aString + "Answer an OrderedCollection of RBTokens in aString, a String + taken from RBMethodNode>>#primitiveSources." + | tokens scanner currentToken start | + tokens := OrderedCollection new. + scanner := RBScanner on: aString readStream + errorBlock: [:desc :pos | self compileError: desc]. + + "Adapted from RBParser>>#parseResourceTag; this version saves the + resulting tokens instead of source-describing Intervals" + currentToken := scanner next. + (currentToken isBinary and: [currentToken value == #<]) + ifFalse: [^self compileError: + 'method attributes must begin with ''<''']. + currentToken := scanner next. + [scanner atEnd or: [currentToken isBinary and: [currentToken value == #>]]] + whileFalse: [tokens add: currentToken. + currentToken := scanner next]. + (currentToken isBinary and: [currentToken value == #>]) + ifFalse: [^self compileError: 'method attributes must end with ''>''']. + ^tokens +! + +compileAsyncCCall: nameToken args: argsToken + self warnUnimplementedAttribute: #asyncCCall:args: +! + +compileCCall: nameToken returning: rettypeToken args: argsToken + self warnUnimplementedAttribute: #cCall:returning:args: +! + +compilePrimitive: identifierToken + self warnUnimplementedAttribute: #primitive: +! + +warnUnimplementedAttribute: selector + self compileWarning: ('<%1> tag not yet implemented' + bindWith: selector) +! ! + STCompiler initialize! diff -rdu smalltalk-2.3.1/kernel/PosStream.st smalltalk/kernel/PosStream.st --- smalltalk-2.3.1/kernel/PosStream.st 2006-02-05 12:41:27.000000000 -0600 +++ smalltalk/kernel/PosStream.st 2006-12-30 21:51:56.000000000 -0600 @@ -109,7 +109,7 @@ "Answer the collection on which the receiver is streaming, from the start-th item to the end-th" - ^collection copyFrom: start to: end + ^collection copyFrom: start + 1 to: end + 1 ! contents