Browse Source

Merge branch 'line_numbers' into message_send

* line_numbers:
  parser.js: regenerate parser
  parser.pegjs: add line/column to generated nodes
  boot.js: _st() returns nil if argument is null
  parser.pegjs: cleanup tab/whitespace mix with spaces only
  Compiler-AST/Node: add position instance var + accessors
mkroehnert 12 years ago
parent
commit
654a855f4c
6 changed files with 520 additions and 389 deletions
  1. 30 1
      js/Compiler-AST.deploy.js
  2. 41 2
      js/Compiler-AST.js
  3. 1 0
      js/boot.js
  4. 255 222
      js/parser.js
  5. 181 162
      js/parser.pegjs
  6. 12 2
      st/Compiler-AST.st

+ 30 - 1
js/Compiler-AST.deploy.js

@@ -1,5 +1,5 @@
 smalltalk.addPackage('Compiler-AST', {});
-smalltalk.addClass('Node', smalltalk.Object, ['nodes', 'shouldBeInlined', 'shouldBeAliased'], 'Compiler-AST');
+smalltalk.addClass('Node', smalltalk.Object, ['position', 'nodes', 'shouldBeInlined', 'shouldBeAliased'], 'Compiler-AST');
 smalltalk.addMethod(
 "_accept_",
 smalltalk.method({
@@ -119,6 +119,35 @@ return self}
 }),
 smalltalk.Node);
 
+smalltalk.addMethod(
+"_position",
+smalltalk.method({
+selector: "position",
+fn: function (){
+var self=this;
+var $1;
+if(($receiver = self["@position"]) == nil || $receiver == undefined){
+self["@position"]=_st((0)).__at((0));
+$1=self["@position"];
+} else {
+$1=self["@position"];
+};
+return $1;
+}
+}),
+smalltalk.Node);
+
+smalltalk.addMethod(
+"_position_",
+smalltalk.method({
+selector: "position:",
+fn: function (aPosition){
+var self=this;
+self["@position"]=aPosition;
+return self}
+}),
+smalltalk.Node);
+
 smalltalk.addMethod(
 "_shouldBeAliased",
 smalltalk.method({

+ 41 - 2
js/Compiler-AST.js

@@ -1,6 +1,6 @@
 smalltalk.addPackage('Compiler-AST', {});
-smalltalk.addClass('Node', smalltalk.Object, ['nodes', 'shouldBeInlined', 'shouldBeAliased'], 'Compiler-AST');
-smalltalk.Node.comment="I am the abstract root class of the abstract syntax tree."
+smalltalk.addClass('Node', smalltalk.Object, ['position', 'nodes', 'shouldBeInlined', 'shouldBeAliased'], 'Compiler-AST');
+smalltalk.Node.comment="I am the abstract root class of the abstract syntax tree.\x0a\x0aposition: holds a point containing lline- and column number of the symbol location in the original source file"
 smalltalk.addMethod(
 "_accept_",
 smalltalk.method({
@@ -170,6 +170,45 @@ referencedClasses: []
 }),
 smalltalk.Node);
 
+smalltalk.addMethod(
+"_position",
+smalltalk.method({
+selector: "position",
+category: 'accessing',
+fn: function (){
+var self=this;
+var $1;
+if(($receiver = self["@position"]) == nil || $receiver == undefined){
+self["@position"]=_st((0)).__at((0));
+$1=self["@position"];
+} else {
+$1=self["@position"];
+};
+return $1;
+},
+args: [],
+source: "position\x0a\x09^position ifNil: [position := 0@0]",
+messageSends: ["ifNil:", "@"],
+referencedClasses: []
+}),
+smalltalk.Node);
+
+smalltalk.addMethod(
+"_position_",
+smalltalk.method({
+selector: "position:",
+category: 'building',
+fn: function (aPosition){
+var self=this;
+self["@position"]=aPosition;
+return self},
+args: ["aPosition"],
+source: "position: aPosition\x0a\x09position := aPosition",
+messageSends: [],
+referencedClasses: []
+}),
+smalltalk.Node);
+
 smalltalk.addMethod(
 "_shouldBeAliased",
 smalltalk.method({

+ 1 - 0
js/boot.js

@@ -793,6 +793,7 @@ if(this.jQuery) {
 
 var _st = function(o) {
 	if(typeof o === 'undefined') {return nil}
+	if(null === o) {return nil}
 	if(o.klass) {return o}
 	return smalltalk.JSObjectProxy._on_(o);
 }; 

File diff suppressed because it is too large
+ 255 - 222
js/parser.js


+ 181 - 162
js/parser.pegjs

@@ -8,51 +8,62 @@ varIdentifier  = first:[a-z] others:[a-zA-Z0-9]* {return first + others.join("")
 keyword        = first:identifier last:[:] {return first + last}
 className      = first:[A-Z] others:[a-zA-Z0-9]* {return first + others.join("")}
 string         = ['] val:(("''" {return "'"} / [^'])*) ['] {
-               	   return smalltalk.ValueNode._new()
-               	   	._value_(val.join("").replace(/\"/ig, '"'))
-	         }
+                     return smalltalk.ValueNode._new()
+                            ._position_((line).__at(column))
+                            ._value_(val.join("").replace(/\"/ig, '"'));
+                 }
 
 symbol         = "#"val:(
-			digits:[a-zA-Z0-9\:]+ {return digits.join("")} / 
-			node:string {return node._value()})* {
-		  		    return smalltalk.ValueNode._new()
-               	   		    	   ._value_(smalltalk.symbolFor(val.join("").replace(/\"/ig, '"')))
-               	 }
+                         digits:[a-zA-Z0-9\:]+ {return digits.join("")}
+                       / node:string {return node._value()})*
+                  {
+                      return smalltalk.ValueNode._new()
+                             ._position_((line).__at(column))
+                             ._value_(smalltalk.symbolFor(val.join("").replace(/\"/ig, '"')))
+                  }
 number         = n:(float / integer) {
-		  return smalltalk.ValueNode._new()
-               	   	._value_(n)
-               	 }
+                     return smalltalk.ValueNode._new()
+                            ._position_((line).__at(column))
+                            ._value_(n)
+                 }
 float          = neg:[-]?int:[0-9]+ "." dec:[0-9]+ {return parseFloat((neg + int.join("") + "." + dec.join("")), 10)}
 integer        = neg:[-]?digits:[0-9]+ {return (parseInt(neg+digits.join(""), 10))}
 literalArray   = "#(" ws lits:(lit:literal ws {return lit._value()})* ws ")" {
-		  return smalltalk.ValueNode._new()
-               	   	._value_(lits)
-               	 }
+                     return smalltalk.ValueNode._new()
+                            ._position_((line).__at(column))
+                            ._value_(lits)
+                 }
 dynamicArray   = "{" ws expressions:expressions? ws "."? "}" {
-	       	  return smalltalk.DynamicArrayNode._new()
-		        ._nodes_(expressions)
-		  }
+                     return smalltalk.DynamicArrayNode._new()
+                            ._position_((line).__at(column))
+                            ._nodes_(expressions)
+                 }
 dynamicDictionary = "#{" ws expressions: expressions? ws "}" {
-	       	  return smalltalk.DynamicDictionaryNode._new()
-		        ._nodes_(expressions)
-		  }
+                        return smalltalk.DynamicDictionaryNode._new()
+                               ._position_((line).__at(column))
+                               ._nodes_(expressions)
+                    }
 pseudoVariable = val:(
-	          'true' {return true} 
-	       	/ 'false' {return false}
-		/ 'nil' {return nil}) {
-			return smalltalk.ValueNode._new()._value_(val)
-		    }
+                   'true' {return true}
+                 / 'false' {return false}
+                 / 'nil' {return nil}) {
+                       return smalltalk.ValueNode._new()
+                              ._position_((line).__at(column))
+                              ._value_(val)
+                   }
 literal        = pseudoVariable / number / literalArray / dynamicDictionary / dynamicArray / string / symbol / block
 
 
 variable       = identifier:varIdentifier {
-		  return smalltalk.VariableNode._new()
-			._value_(identifier)
-		  }
+                     return smalltalk.VariableNode._new()
+                            ._position_((line).__at(column))
+                            ._value_(identifier)
+                 }
 classReference = className:className {
-		  return smalltalk.ClassReferenceNode._new()
-		  	._value_(className)
-		  }
+                     return smalltalk.ClassReferenceNode._new()
+                            ._position_((line).__at(column))
+                            ._value_(className)
+                 }
 
 reference      = variable / classReference
 
@@ -62,7 +73,7 @@ binarySelector = bin:[\\+*/=><,@%~|&-]+ {return bin.join("").replace(/\\/g, '\\\
 unarySelector  = identifier
 
 keywordPattern = pairs:(ws key:keyword ws arg:identifier {return {key:key, arg: arg}})+ {
-	             var keywords = [];
+                     var keywords = [];
                      var params = [];
                      for(var i=0;i<pairs.length;i++){
                          keywords.push(pairs[i].key);
@@ -70,8 +81,8 @@ keywordPattern = pairs:(ws key:keyword ws arg:identifier {return {key:key, arg:
                      for(var i=0;i<pairs.length;i++){
                          params.push(pairs[i].arg);
                      }
-		     return [keywords.join(""), params]
-	         }
+                     return [keywords.join(""), params]
+                 }
 binaryPattern  = ws selector:binarySelector ws arg:identifier {return [selector, [arg]]}
 unaryPattern   = ws selector:unarySelector {return [selector, []]}
 
@@ -79,23 +90,25 @@ expression     = assignment / cascade / keywordSend / binarySend / jsStatement
 
 expressionList = ws "." ws expression:expression {return expression}
 expressions    = first:expression others:expressionList* {
-	       	     var result = [first];
-		     for(var i=0;i<others.length;i++) {
-		 	 result.push(others[i]);
-		     }
-		     return result;
-	       } 
+                     var result = [first];
+                     for(var i=0;i<others.length;i++) {
+                         result.push(others[i]);
+                     }
+                     return result;
+                 }
 
 assignment     = variable:variable ws ':=' ws expression:expression {
-	       	     return smalltalk.AssignmentNode._new()
-	       	     	._left_(variable)
-	       	     	._right_(expression)
-		 }
+                     return smalltalk.AssignmentNode._new()
+                            ._position_((line).__at(column))
+                            ._left_(variable)
+                            ._right_(expression)
+                 }
 
 ret            = '^' ws expression:expression ws '.'? {
-	       	     return smalltalk.ReturnNode._new()
-	       	     	._nodes_([expression])
-	       }
+                     return smalltalk.ReturnNode._new()
+                            ._position_((line).__at(column))
+                            ._nodes_([expression])
+                 }
   
 temps          = "|" vars:(ws variable:identifier ws {return variable})* "|" {return vars}
 
@@ -103,121 +116,127 @@ blockParamList = params:((ws ":" ws param:identifier {return param})+) ws "|" {r
 
 subexpression  = '(' ws expression:expression ws ')' {return expression}
 
-statements    = ret:ret [.]* {return [ret]}
-  	      / exps:expressions ws [.]+ ws ret:ret [.]* {
-      	      	  var expressions = exps;
-      		  expressions.push(ret);
-      		  return expressions
-  		}
-  	      / expressions:expressions? [.]* {
-      	          return expressions || []
-  	        }
-
-sequence      = temps:temps? ws statements:statements? ws {
-	      	  return smalltalk.SequenceNode._new()
-	      	  	._temps_(temps || [])
-	      	  	._nodes_(statements || [])
-		}
-
-block         = '[' ws params:blockParamList? ws sequence:sequence? ws ']' {
-	          return smalltalk.BlockNode._new()
-	          	._parameters_(params || [])
-	          	._nodes_([sequence._asBlockSequenceNode()])
-		}
-
-operand       = literal / reference / subexpression
-
-
-
-unaryMessage  = ws selector:unarySelector ![:] {
-	      	return smalltalk.SendNode._new()
-	      		._selector_(selector)
-	      }
-
-unaryTail     = message:unaryMessage ws tail:unaryTail? ws {
-		  if(tail) {
-          	      return tail._valueForReceiver_(message);
-      		  }
-      		  else {
-          	      return message;
-      		  }
-  	      }
-
-unarySend     = receiver:operand ws tail:unaryTail? {
-		  if(tail) {
-          	      return tail._valueForReceiver_(receiver);
-      		  }
-      		  else {
-          	      return receiver;
-      		  }
-	      }
-
-binaryMessage = ws selector:binarySelector ws arg:(unarySend / operand) {
-	          return smalltalk.SendNode._new()
-	          	._selector_(selector)
-	          	._arguments_([arg])
-	      }
-
-binaryTail    = message:binaryMessage tail:binaryTail? {
-      	          if(tail) {
-          	      return tail._valueForReceiver_(message);
-      		  }
-      		  else {
-          	      return message;
-      		  }
-  	      }
-
-binarySend    = receiver:unarySend tail:binaryTail? {
-	      	  if(tail) {
-          	      return tail._valueForReceiver_(receiver);
-      		  }
-      		  else {
-          	      return receiver;
-      		  }
-	      }
-	      
+statements     = ret:ret [.]* {return [ret]}
+                 / exps:expressions ws [.]+ ws ret:ret [.]* {
+                       var expressions = exps;
+                       expressions.push(ret);
+                       return expressions
+                   }
+                 / expressions:expressions? [.]* {
+                       return expressions || []
+                   }
+
+sequence       = temps:temps? ws statements:statements? ws {
+                     return smalltalk.SequenceNode._new()
+                            ._position_((line).__at(column))
+                            ._temps_(temps || [])
+                            ._nodes_(statements || [])
+                 }
+
+block          = '[' ws params:blockParamList? ws sequence:sequence? ws ']' {
+                     return smalltalk.BlockNode._new()
+                            ._position_((line).__at(column))
+                            ._parameters_(params || [])
+                            ._nodes_([sequence._asBlockSequenceNode()])
+                 }
+
+operand        = literal / reference / subexpression
+
+
+
+unaryMessage   = ws selector:unarySelector ![:] {
+                     return smalltalk.SendNode._new()
+                            ._position_((line).__at(column))
+                            ._selector_(selector)
+                 }
+
+unaryTail      = message:unaryMessage ws tail:unaryTail? ws {
+                     if(tail) {
+                         return tail._valueForReceiver_(message);
+                     }
+                     else {
+                         return message;
+                     }
+                 }
+
+unarySend      = receiver:operand ws tail:unaryTail? {
+                     if(tail) {
+                         return tail._valueForReceiver_(receiver);
+                     }
+                     else {
+                         return receiver;
+                     }
+                 }
+
+binaryMessage  = ws selector:binarySelector ws arg:(unarySend / operand) {
+                     return smalltalk.SendNode._new()
+                            ._position_((line).__at(column))
+                            ._selector_(selector)
+                            ._arguments_([arg])
+                 }
+
+binaryTail     = message:binaryMessage tail:binaryTail? {
+                     if(tail) {
+                         return tail._valueForReceiver_(message);
+                      }
+                     else {
+                         return message;
+                     }
+                 }
+
+binarySend     = receiver:unarySend tail:binaryTail? {
+                     if(tail) {
+                         return tail._valueForReceiver_(receiver);
+                     }
+                     else {
+                         return receiver;
+                     }
+                 }
+
 
 keywordMessage = ws pairs:(pair:keywordPair ws {return pair})+ {
-      		  var selector = [];
-      		  var args = [];
-      		  for(var i=0;i<pairs.length;i++) {
-          	      selector.push(pairs[i].key);
-          	      args.push(pairs[i].arg);
-      		  }
-      		  return smalltalk.SendNode._new()
-      		  	._selector_(selector.join(""))
-      		  	._arguments_(args)
-  	      }
-
-keywordSend   = receiver:binarySend tail:keywordMessage {
-	          return tail._valueForReceiver_(receiver);
-	      }
-
-message       = binaryMessage / unaryMessage / keywordMessage
-
-cascade       = ws send:(keywordSend / binarySend) messages:(ws ";" ws mess:message ws {return mess})+ 
-  	      {
-		var cascade = [];
-      		cascade.push(send);
-      		for(var i=0;i<messages.length;i++) {
-          		cascade.push(messages[i]);
-      		}
-      		return smalltalk.CascadeNode._new()
-          	       ._receiver_(send._receiver())
-          	       ._nodes_(cascade)
-  	      }
-
-jsStatement   = "<" val:((">>" {return ">"} / [^>])*) ">"
-  	      {
-		return smalltalk.JSStatementNode._new()
-			._source_(val.join(""))
-  	      }
-
-
-method        = ws pattern:(keywordPattern / binaryPattern / unaryPattern) ws sequence:sequence? ws {
-	      	return smalltalk.MethodNode._new()
-		       ._selector_(pattern[0])
-		       ._arguments_(pattern[1])
-		       ._nodes_([sequence])
-	      }
+                     var selector = [];
+                     var args = [];
+                      for(var i=0;i<pairs.length;i++) {
+                          selector.push(pairs[i].key);
+                          args.push(pairs[i].arg);
+                      }
+                      return smalltalk.SendNode._new()
+                             ._position_((line).__at(column))
+                             ._selector_(selector.join(""))
+                             ._arguments_(args)
+                 }
+
+keywordSend    = receiver:binarySend tail:keywordMessage {
+                     return tail._valueForReceiver_(receiver);
+                 }
+
+message        = binaryMessage / unaryMessage / keywordMessage
+
+cascade        = ws send:(keywordSend / binarySend) messages:(ws ";" ws mess:message ws {return mess})+ {
+                     var cascade = [];
+                     cascade.push(send);
+                     for(var i=0;i<messages.length;i++) {
+                         cascade.push(messages[i]);
+                     }
+                     return smalltalk.CascadeNode._new()
+                            ._position_((line).__at(column))
+                            ._receiver_(send._receiver())
+                            ._nodes_(cascade)
+                 }
+
+jsStatement    = "<" val:((">>" {return ">"} / [^>])*) ">" {
+                     return smalltalk.JSStatementNode._new()
+                            ._position_((line).__at(column))
+                            ._source_(val.join(""))
+                 }
+
+
+method         = ws pattern:(keywordPattern / binaryPattern / unaryPattern) ws sequence:sequence? ws {
+                      return smalltalk.MethodNode._new()
+                             ._position_((line).__at(column))
+                             ._selector_(pattern[0])
+                             ._arguments_(pattern[1])
+                             ._nodes_([sequence])
+                 }
 

+ 12 - 2
st/Compiler-AST.st

@@ -1,9 +1,11 @@
 Smalltalk current createPackage: 'Compiler-AST' properties: #{}!
 Object subclass: #Node
-	instanceVariableNames: 'nodes shouldBeInlined shouldBeAliased'
+	instanceVariableNames: 'position nodes shouldBeInlined shouldBeAliased'
 	package: 'Compiler-AST'!
 !Node commentStamp!
-I am the abstract root class of the abstract syntax tree.!
+I am the abstract root class of the abstract syntax tree.
+
+position: holds a point containing lline- and column number of the symbol location in the original source file!
 
 !Node methodsFor: 'accessing'!
 
@@ -15,6 +17,10 @@ nodes
 	^nodes ifNil: [nodes := Array new]
 !
 
+position
+	^position ifNil: [position := 0@0]
+!
+
 shouldBeAliased
 	^ shouldBeAliased ifNil: [ false ]
 !
@@ -35,6 +41,10 @@ shouldBeInlined: aBoolean
 
 nodes: aCollection
 	nodes := aCollection
+!
+
+position: aPosition
+	position := aPosition
 ! !
 
 !Node methodsFor: 'testing'!

Some files were not shown because too many files changed in this diff