Browse Source

Add String>>capitalized and isCapitalized.

Matthias Springer 10 years ago
parent
commit
467f45ada3

+ 3 - 3
js/Compiler-Interpreter.js

@@ -1970,7 +1970,7 @@ $4=_st(_st(self._context())._receiver())._instVarAt_(_st(aNode)._value());
 } else {
 $4=_st(self._context())._localAt_ifAbsent_(_st(aNode)._value(),(function(){
 return smalltalk.withContext(function($ctx2) {
-$6=_st(_st(aNode)._value())._beginsWithCapital();
+$6=_st(_st(aNode)._value())._isCapitalized();
 if(smalltalk.assert($6)){
 return _st(_st($Smalltalk())._current())._at_ifAbsent_(_st(aNode)._value(),(function(){
 return smalltalk.withContext(function($ctx3) {
@@ -1982,8 +1982,8 @@ return _st(_st($PlatformInterface())._globals())._at_(_st(aNode)._value());
 _st($3)._push_($4);
 return self}, function($ctx1) {$ctx1.fill(self,"visitVariableNode:",{aNode:aNode},smalltalk.ASTInterpreter)})},
 args: ["aNode"],
-source: "visitVariableNode: aNode\x0a\x09aNode binding isUnknownVar ifTrue: [\x0a\x09\x09^ self push: (PlatformInterface globals at: aNode value ifAbsent: [ self error: 'Unknown variable' ]) ].\x0a\x09\x09\x0a\x09self push: (aNode binding isInstanceVar\x0a\x09\x09ifTrue: [ self context receiver instVarAt: aNode value ]\x0a\x09\x09ifFalse: [ self context \x0a\x09\x09\x09localAt: aNode value\x0a\x09\x09\x09ifAbsent: [\x0a\x09\x09\x09\x09aNode value beginsWithCapital\x0a\x09\x09\x09\x09\x09ifTrue: [\x0a\x09\x09\x09\x09\x09\x09Smalltalk current \x0a\x09\x09\x09\x09\x09\x09\x09at: aNode value \x0a\x09\x09\x09\x09\x09\x09\x09ifAbsent: [ PlatformInterface globals at: aNode value ]]]])",
-messageSends: ["ifTrue:", "isUnknownVar", "binding", "push:", "at:ifAbsent:", "globals", "value", "error:", "ifTrue:ifFalse:", "isInstanceVar", "instVarAt:", "receiver", "context", "localAt:ifAbsent:", "beginsWithCapital", "current", "at:"],
+source: "visitVariableNode: aNode\x0a\x09aNode binding isUnknownVar ifTrue: [\x0a\x09\x09^ self push: (PlatformInterface globals at: aNode value ifAbsent: [ self error: 'Unknown variable' ]) ].\x0a\x09\x09\x0a\x09self push: (aNode binding isInstanceVar\x0a\x09\x09ifTrue: [ self context receiver instVarAt: aNode value ]\x0a\x09\x09ifFalse: [ self context \x0a\x09\x09\x09localAt: aNode value\x0a\x09\x09\x09ifAbsent: [\x0a\x09\x09\x09\x09aNode value isCapitalized\x0a\x09\x09\x09\x09\x09ifTrue: [\x0a\x09\x09\x09\x09\x09\x09Smalltalk current \x0a\x09\x09\x09\x09\x09\x09\x09at: aNode value \x0a\x09\x09\x09\x09\x09\x09\x09ifAbsent: [ PlatformInterface globals at: aNode value ]]]])",
+messageSends: ["ifTrue:", "isUnknownVar", "binding", "push:", "at:ifAbsent:", "globals", "value", "error:", "ifTrue:ifFalse:", "isInstanceVar", "instVarAt:", "receiver", "context", "localAt:ifAbsent:", "isCapitalized", "current", "at:"],
 referencedClasses: ["PlatformInterface", "Smalltalk"]
 }),
 smalltalk.ASTInterpreter);

+ 4 - 22
js/Compiler-Semantic.js

@@ -1,4 +1,4 @@
-define("amber_core/Compiler-Semantic", ["amber_vm/smalltalk", "amber_vm/nil", "amber_vm/_st", "amber_core/Kernel-Objects", "amber_core/Compiler-Core", "amber_core/Kernel-Collections"], function(smalltalk,nil,_st){
+define("amber_core/Compiler-Semantic", ["amber_vm/smalltalk", "amber_vm/nil", "amber_vm/_st", "amber_core/Kernel-Objects", "amber_core/Compiler-Core"], function(smalltalk,nil,_st){
 smalltalk.addPackage('Compiler-Semantic');
 smalltalk.packages["Compiler-Semantic"].transport = {"type":"amd","amdNamespace":"amber_core"};
 
@@ -1782,7 +1782,7 @@ var $1,$2,$3,$4,$5,$6;
 binding=_st(self["@currentScope"])._lookupVariable_(aNode);
 $1=binding;
 if(($receiver = $1) == nil || $receiver == null){
-$2=_st(_st(aNode)._value())._beginsWithCapital();
+$2=_st(_st(aNode)._value())._isCapitalized();
 if(smalltalk.assert($2)){
 $3=_st($ClassRefVar())._new();
 _st($3)._name_(_st(aNode)._value());
@@ -1804,8 +1804,8 @@ $1;
 _st(aNode)._binding_(binding);
 return self}, function($ctx1) {$ctx1.fill(self,"visitVariableNode:",{aNode:aNode,binding:binding},smalltalk.SemanticAnalyzer)})},
 args: ["aNode"],
-source: "visitVariableNode: aNode\x0a\x09\x22Bind a ScopeVar to aNode by doing a lookup in the current scope.\x0a\x09If no ScopeVar is found, bind a UnknowVar and throw an error.\x22\x0a\x0a\x09| binding |\x0a\x09binding := currentScope lookupVariable: aNode.\x0a\x09\x0a\x09binding ifNil: [\x0a\x09\x09aNode value beginsWithCapital\x0a\x09\x09\x09ifTrue: [ \x22Capital letter variables might be globals.\x22\x0a\x09\x09\x09\x09binding := ClassRefVar new name: aNode value; yourself.\x0a\x09\x09\x09\x09self classReferences add: aNode value]\x0a\x09\x09\x09ifFalse: [\x0a\x09\x09\x09\x09self errorUnknownVariable: aNode.\x0a\x09\x09\x09\x09binding := UnknownVar new name: aNode value; yourself ] ].\x0a\x09\x09\x0a\x09aNode binding: binding.",
-messageSends: ["lookupVariable:", "ifNil:", "ifTrue:ifFalse:", "beginsWithCapital", "value", "name:", "new", "yourself", "add:", "classReferences", "errorUnknownVariable:", "binding:"],
+source: "visitVariableNode: aNode\x0a\x09\x22Bind a ScopeVar to aNode by doing a lookup in the current scope.\x0a\x09If no ScopeVar is found, bind a UnknowVar and throw an error.\x22\x0a\x0a\x09| binding |\x0a\x09binding := currentScope lookupVariable: aNode.\x0a\x09\x0a\x09binding ifNil: [\x0a\x09\x09aNode value isCapitalized\x0a\x09\x09\x09ifTrue: [ \x22Capital letter variables might be globals.\x22\x0a\x09\x09\x09\x09binding := ClassRefVar new name: aNode value; yourself.\x0a\x09\x09\x09\x09self classReferences add: aNode value]\x0a\x09\x09\x09ifFalse: [\x0a\x09\x09\x09\x09self errorUnknownVariable: aNode.\x0a\x09\x09\x09\x09binding := UnknownVar new name: aNode value; yourself ] ].\x0a\x09\x09\x0a\x09aNode binding: binding.",
+messageSends: ["lookupVariable:", "ifNil:", "ifTrue:ifFalse:", "isCapitalized", "value", "name:", "new", "yourself", "add:", "classReferences", "errorUnknownVariable:", "binding:"],
 referencedClasses: ["ClassRefVar", "UnknownVar"]
 }),
 smalltalk.SemanticAnalyzer);
@@ -1832,22 +1832,4 @@ referencedClasses: []
 }),
 smalltalk.SemanticAnalyzer.klass);
 
-smalltalk.addMethod(
-smalltalk.method({
-selector: "beginsWithCapital",
-category: '*Compiler-Semantic',
-fn: function (){
-var self=this;
-return smalltalk.withContext(function($ctx1) { 
-var $1;
-$1=_st(_st(self._first())._asUppercase()).__eq_eq(self._first());
-return $1;
-}, function($ctx1) {$ctx1.fill(self,"beginsWithCapital",{},smalltalk.String)})},
-args: [],
-source: "beginsWithCapital\x0a\x09^ self first asUppercase == self first",
-messageSends: ["==", "asUppercase", "first"],
-referencedClasses: []
-}),
-smalltalk.String);
-
 });

+ 36 - 0
js/Kernel-Collections.js

@@ -3828,6 +3828,24 @@ referencedClasses: []
 }),
 smalltalk.String);
 
+smalltalk.addMethod(
+smalltalk.method({
+selector: "capitalized",
+category: 'converting',
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+var $1;
+$1=_st(_st(self._copyFrom_to_((1),(1)))._asUppercase()).__comma(self._copyFrom_to_((2),self._size()));
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"capitalized",{},smalltalk.String)})},
+args: [],
+source: "capitalized\x0a\x09^ (self copyFrom: 1 to: 1) asUppercase, (self copyFrom: 2 to: self size)",
+messageSends: [",", "asUppercase", "copyFrom:to:", "size"],
+referencedClasses: []
+}),
+smalltalk.String);
+
 smalltalk.addMethod(
 smalltalk.method({
 selector: "charCodeAt:",
@@ -3945,6 +3963,24 @@ referencedClasses: []
 }),
 smalltalk.String);
 
+smalltalk.addMethod(
+smalltalk.method({
+selector: "isCapitalized",
+category: 'testing',
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+var $1;
+$1=_st(_st(self._first())._asUppercase()).__eq_eq(self._first());
+return $1;
+}, function($ctx1) {$ctx1.fill(self,"isCapitalized",{},smalltalk.String)})},
+args: [],
+source: "isCapitalized\x0a\x09^ self first asUppercase == self first",
+messageSends: ["==", "asUppercase", "first"],
+referencedClasses: []
+}),
+smalltalk.String);
+
 smalltalk.addMethod(
 smalltalk.method({
 selector: "isImmutable",

+ 20 - 0
js/Kernel-Tests.js

@@ -2299,6 +2299,26 @@ referencedClasses: ["Error"]
 }),
 smalltalk.StringTest);
 
+smalltalk.addMethod(
+smalltalk.method({
+selector: "testCapitalized",
+category: 'tests',
+fn: function (){
+var self=this;
+return smalltalk.withContext(function($ctx1) { 
+self._assert_equals_("test"._capitalized(),"Test");
+self._assert_equals_("Test"._capitalized(),"Test");
+self._assert_equals_(""._capitalized(),"");
+self._assert_equals_("Test"._isCapitalized(),true);
+self._assert_equals_("test"._isCapitalized(),false);
+return self}, function($ctx1) {$ctx1.fill(self,"testCapitalized",{},smalltalk.StringTest)})},
+args: [],
+source: "testCapitalized\x0a\x09self assert: 'test' capitalized equals: 'Test'.\x0a\x09self assert: 'Test' capitalized equals: 'Test'.\x0a\x09self assert: '' capitalized equals: ''.\x0a\x09self assert: 'Test' isCapitalized equals: true.\x0a\x09self assert: 'test' isCapitalized equals: false.",
+messageSends: ["assert:equals:", "capitalized", "isCapitalized"],
+referencedClasses: []
+}),
+smalltalk.StringTest);
+
 smalltalk.addMethod(
 smalltalk.method({
 selector: "testCollect",

+ 10 - 10
st/Compiler-Interpreter.st

@@ -129,6 +129,15 @@ localAt: aString
 			context localAt: aString ] ]
 !
 
+localAt: aString ifAbsent: aBlock
+	"Lookup the local value up to the method context"
+
+	^ self locals at: aString ifAbsent: [ 
+		self outerContext 
+			ifNotNil: [ :context | context localAt: aString ifAbsent: aBlock ]
+			ifNil: [aBlock value] ]
+!
+
 localAt: aString put: anObject
 	self locals at: aString put: anObject
 !
@@ -159,15 +168,6 @@ selector
 
 selector: aString
 	selector := aString
-!
-
-localAt: aString ifAbsent: aBlock
-	"Lookup the local value up to the method context"
-
-	^ self locals at: aString ifAbsent: [ 
-		self outerContext 
-			ifNotNil: [ :context | context localAt: aString ifAbsent: aBlock ]
-			ifNil: [aBlock value] ]
 ! !
 
 !AIContext methodsFor: 'factory'!
@@ -694,7 +694,7 @@ visitVariableNode: aNode
 		ifFalse: [ self context 
 			localAt: aNode value
 			ifAbsent: [
-				aNode value beginsWithCapital
+				aNode value isCapitalized
 					ifTrue: [
 						Smalltalk current 
 							at: aNode value 

+ 1 - 7
st/Compiler-Semantic.st

@@ -587,7 +587,7 @@ visitVariableNode: aNode
 	binding := currentScope lookupVariable: aNode.
 	
 	binding ifNil: [
-		aNode value beginsWithCapital
+		aNode value isCapitalized
 			ifTrue: [ "Capital letter variables might be globals."
 				binding := ClassRefVar new name: aNode value; yourself.
 				self classReferences add: aNode value]
@@ -606,9 +606,3 @@ on: aClass
 		yourself
 ! !
 
-!String methodsFor: '*Compiler-Semantic'!
-
-beginsWithCapital
-	^ self first asUppercase == self first
-! !
-

+ 8 - 0
st/Kernel-Collections.st

@@ -1315,6 +1315,10 @@ crlfSanitized
 
 reversed
 	<return self.split("").reverse().join("")>
+!
+
+capitalized
+	^ (self copyFrom: 1 to: 1) asUppercase, (self copyFrom: 2 to: self size)
 ! !
 
 !String methodsFor: 'copying'!
@@ -1500,6 +1504,10 @@ isVowel
 	"Answer true if the receiver is a one character string containing a voyel"
 	
 	^ self size = 1 and: [ 'aeiou' includes: self asLowercase ]
+!
+
+isCapitalized
+	^ self first asUppercase == self first
 ! !
 
 !String class methodsFor: 'accessing'!

+ 8 - 0
st/Kernel-Tests.st

@@ -967,6 +967,14 @@ testStreamContents
 				nextPutAll: 'hello'; space;
 				nextPutAll: 'world' ])
 		equals: 'hello world'
+!
+
+testCapitalized
+	self assert: 'test' capitalized equals: 'Test'.
+	self assert: 'Test' capitalized equals: 'Test'.
+	self assert: '' capitalized equals: ''.
+	self assert: 'Test' isCapitalized equals: true.
+	self assert: 'test' isCapitalized equals: false.
 ! !
 
 !StringTest class methodsFor: 'accessing'!