[Pkg-puppet-devel] [SCM] Puppet packaging for Debian branch, master, updated. debian/0.24.6-1-356-g5718585

Brice Figureau brice at daysofwonder.com
Fri Jan 23 14:21:04 UTC 2009


The following commit has been merged in the master branch:
commit cfa230a2d7b0c5e57cc0379785bd2025520f1c35
Author: Brice Figureau <brice-puppet at daysofwonder.com>
Date:   Fri Sep 26 22:54:42 2008 +0200

    Add arithmetic operators to AST
    
    This changeset adds +,-,/,*,<< and >> computation and
    AST parse nodes.

diff --git a/lib/puppet/parser/ast.rb b/lib/puppet/parser/ast.rb
index 5727712..5aa9f52 100644
--- a/lib/puppet/parser/ast.rb
+++ b/lib/puppet/parser/ast.rb
@@ -74,6 +74,7 @@ class Puppet::Parser::AST
 end
 
 # And include all of the AST subclasses.
+require 'puppet/parser/ast/arithmetic_operator'
 require 'puppet/parser/ast/astarray'
 require 'puppet/parser/ast/branch'
 require 'puppet/parser/ast/boolean_operator'
@@ -88,6 +89,7 @@ require 'puppet/parser/ast/function'
 require 'puppet/parser/ast/hostclass'
 require 'puppet/parser/ast/ifstatement'
 require 'puppet/parser/ast/leaf'
+require 'puppet/parser/ast/minus'
 require 'puppet/parser/ast/node'
 require 'puppet/parser/ast/not'
 require 'puppet/parser/ast/resource'
diff --git a/lib/puppet/parser/ast/comparison_operator.rb b/lib/puppet/parser/ast/arithmetic_operator.rb
similarity index 54%
copy from lib/puppet/parser/ast/comparison_operator.rb
copy to lib/puppet/parser/ast/arithmetic_operator.rb
index 63aa36c..8d9cef8 100644
--- a/lib/puppet/parser/ast/comparison_operator.rb
+++ b/lib/puppet/parser/ast/arithmetic_operator.rb
@@ -2,7 +2,7 @@ require 'puppet'
 require 'puppet/parser/ast/branch'
 
 class Puppet::Parser::AST
-    class ComparisonOperator < AST::Branch
+    class ArithmeticOperator < AST::Branch
 
         attr_accessor :operator, :lval, :rval
 
@@ -16,21 +16,25 @@ class Puppet::Parser::AST
         def evaluate(scope)
             # evaluate the operands, should return a boolean value
             lval = @lval.safeevaluate(scope)
+            lval = Puppet::Parser::Scope.number?(lval)
+            if lval == nil
+                raise ArgumentError, "left operand of %s is not a number" % @operator
+            end
             rval = @rval.safeevaluate(scope)
-
-            # return result
-            unless @operator == '!='
-                lval.send(@operator,rval)
-            else
-                lval != rval
+            rval = Puppet::Parser::Scope.number?(rval)
+            if rval == nil
+                raise ArgumentError, "right operand of %s is not a number" % @operator
             end
+
+            # compute result
+            lval.send(@operator, rval)
         end
 
         def initialize(hash)
             super
 
-            unless %w{== != < > <= >=}.include?(@operator)
-                raise ArgumentError, "Invalid comparison operator %s" % @operator
+            unless %w{+ - * / << >>}.include?(@operator)
+                raise ArgumentError, "Invalid arithmetic operator %s" % @operator
             end
         end
     end
diff --git a/lib/puppet/parser/ast/not.rb b/lib/puppet/parser/ast/minus.rb
similarity index 60%
copy from lib/puppet/parser/ast/not.rb
copy to lib/puppet/parser/ast/minus.rb
index c8fa1df..b0779a8 100644
--- a/lib/puppet/parser/ast/not.rb
+++ b/lib/puppet/parser/ast/minus.rb
@@ -4,7 +4,7 @@ require 'puppet/parser/ast/branch'
 # An object that returns a boolean which is the boolean not
 # of the given value.
 class Puppet::Parser::AST
-    class Not < AST::Branch
+    class Minus < AST::Branch
         attr_accessor :value
 
         def each
@@ -13,7 +13,11 @@ class Puppet::Parser::AST
 
         def evaluate(scope)
             val = @value.safeevaluate(scope)
-            return ! Puppet::Parser::Scope.true?(val)
+            val = Puppet::Parser::Scope.number?(val)
+            if val == nil
+                raise ArgumentError, "minus operand %s is not a number" % val
+            end
+            return -val
         end
     end
 end
diff --git a/lib/puppet/parser/scope.rb b/lib/puppet/parser/scope.rb
index 1ff998d..4acdf41 100644
--- a/lib/puppet/parser/scope.rb
+++ b/lib/puppet/parser/scope.rb
@@ -43,6 +43,29 @@ class Puppet::Parser::Scope
         end
     end
 
+    # Is the value a number?, return the correct object or nil if not a number
+    def self.number?(value)
+        unless value.is_a?(Fixnum) or value.is_a?(Bignum) or value.is_a?(Float) or value.is_a?(String)
+            return nil
+        end
+        
+        if value.is_a?(String)
+            if value =~ /^-?\d+(:?\.\d+|(:?\.\d+)?e\d+)$/
+                return value.to_f
+            elsif value =~ /^0x\d+/i
+                return value.to_i(16)
+            elsif value =~ /^0\d+/i
+                return value.to_i(8)
+            elsif value =~ /^-?\d+/
+                return value.to_i
+            else
+                return nil
+            end
+        end
+        # it is one of Fixnum,Bignum or Float
+        return value
+    end
+
     # Add to our list of namespaces.
     def add_namespace(ns)
         return false if @namespaces.include?(ns)
diff --git a/spec/unit/parser/ast/arithmetic_operator.rb b/spec/unit/parser/ast/arithmetic_operator.rb
new file mode 100755
index 0000000..24d6ad4
--- /dev/null
+++ b/spec/unit/parser/ast/arithmetic_operator.rb
@@ -0,0 +1,73 @@
+#!/usr/bin/env ruby
+
+require File.dirname(__FILE__) + '/../../../spec_helper'
+
+describe Puppet::Parser::AST::ArithmeticOperator do
+
+		AST = Puppet::Parser::AST
+
+    before :each do
+        @scope = Puppet::Parser::Scope.new()
+        @one = stub 'lval', :safeevaluate => 1
+        @two = stub 'rval', :safeevaluate => 2
+    end
+
+    it "should evaluate both branches" do
+        lval = stub "lval"
+        lval.expects(:safeevaluate).with(@scope).returns(1)
+        rval = stub "rval"
+        rval.expects(:safeevaluate).with(@scope).returns(2)
+        
+        operator = AST::ArithmeticOperator.new :rval => rval, :operator => "+", :lval => lval
+        operator.evaluate(@scope)
+    end
+
+    it "should fail for an unknown operator" do
+        lambda { operator = AST::ArithmeticOperator.new :lval => @one, :operator => "%", :rval => @two }.should raise_error
+    end
+
+    it "should call Puppet::Parser::Scope.number?" do
+				Puppet::Parser::Scope.expects(:number?).with(1).returns(1)
+				Puppet::Parser::Scope.expects(:number?).with(2).returns(2)
+				
+        AST::ArithmeticOperator.new(:lval => @one, :operator => "+", :rval => @two).evaluate(@scope)
+    end
+
+
+		%w{ + - * / << >>}.each do |op|
+    	it "should call ruby Numeric '#{op}'" do
+					one = stub 'one'
+					two = stub 'two'
+        	operator = AST::ArithmeticOperator.new :lval => @one, :operator => op, :rval => @two
+					Puppet::Parser::Scope.stubs(:number?).with(1).returns(one)
+					Puppet::Parser::Scope.stubs(:number?).with(2).returns(two)
+					one.expects(:send).with(op,two)
+        	operator.evaluate(@scope)
+    	end
+		end
+
+    it "should work even with numbers embedded in strings" do
+        two = stub 'two', :safeevaluate => "2"
+        one = stub 'one', :safeevaluate => "1"
+        operator = AST::ArithmeticOperator.new :lval => two, :operator => "+", :rval => one
+        operator.evaluate(@scope).should == 3
+    end
+
+    it "should work even with floats" do
+        two = stub 'two', :safeevaluate => 2.53
+        one = stub 'one', :safeevaluate => 1.80
+        operator = AST::ArithmeticOperator.new :lval => two, :operator => "+", :rval => one
+        operator.evaluate(@scope).should == 4.33
+    end
+
+    it "should work for variables too" do
+        @scope.expects(:lookupvar).with("one").returns(1)
+        @scope.expects(:lookupvar).with("two").returns(2)
+        one = AST::Variable.new( :value => "one" )
+        two = AST::Variable.new( :value => "two" )
+        
+        operator = AST::ArithmeticOperator.new :lval => one, :operator => "+", :rval => two
+        operator.evaluate(@scope).should == 3
+    end
+
+end
diff --git a/spec/unit/parser/ast/minus.rb b/spec/unit/parser/ast/minus.rb
new file mode 100755
index 0000000..83bd92d
--- /dev/null
+++ b/spec/unit/parser/ast/minus.rb
@@ -0,0 +1,36 @@
+#!/usr/bin/env ruby
+
+require File.dirname(__FILE__) + '/../../../spec_helper'
+
+describe Puppet::Parser::AST::Minus do
+    before :each do
+        @scope = Puppet::Parser::Scope.new()
+    end
+
+    it "should evaluate its argument" do
+        value = stub "value"
+        value.expects(:safeevaluate).with(@scope).returns(123)
+        
+        operator = Puppet::Parser::AST::Minus.new :value => value
+        operator.evaluate(@scope)
+    end
+
+    it "should fail if argument is not a string or integer" do
+        array_ast = stub 'array_ast', :safeevaluate => [2]
+        operator = Puppet::Parser::AST::Minus.new :value => array_ast
+        lambda { operator.evaluate(@scope) }.should raise_error
+    end
+
+    it "should work with integer as string" do
+        string = stub 'string', :safeevaluate => "123"
+        operator = Puppet::Parser::AST::Minus.new :value => string
+        operator.evaluate(@scope).should == -123
+    end
+
+    it "should work with integers" do
+        int = stub 'int', :safeevaluate => 123
+        operator = Puppet::Parser::AST::Minus.new :value => int
+        operator.evaluate(@scope).should == -123
+    end
+
+end
diff --git a/spec/unit/parser/scope.rb b/spec/unit/parser/scope.rb
index ec8ab6d..fa76c4f 100755
--- a/spec/unit/parser/scope.rb
+++ b/spec/unit/parser/scope.rb
@@ -34,4 +34,54 @@ describe Puppet::Parser::Scope do
         end
 
     end
+
+    describe Puppet::Parser::Scope, "when calling number?" do
+
+        it "should return nil if called with anything not a number" do
+            Puppet::Parser::Scope.number?([2]).should be_nil
+        end
+
+        it "should return a Fixnum for a Fixnum" do
+            Puppet::Parser::Scope.number?(2).should be_an_instance_of(Fixnum)
+        end
+
+        it "should return a Float for a Float" do
+            Puppet::Parser::Scope.number?(2.34).should be_an_instance_of(Float)
+        end
+
+        it "should return 234 for '234'" do
+            Puppet::Parser::Scope.number?("234").should == 234
+        end
+
+        it "should return nil for 'not a number'" do
+            Puppet::Parser::Scope.number?("not a number").should be_nil
+        end
+
+        it "should return 23.4 for '23.4'" do
+            Puppet::Parser::Scope.number?("23.4").should == 23.4
+        end
+
+        it "should return 23.4e13 for '23.4e13'" do
+            Puppet::Parser::Scope.number?("23.4e13").should == 23.4e13
+        end
+
+        it "should understand negative numbers" do
+            Puppet::Parser::Scope.number?("-234").should == -234
+        end
+
+        it "should know how to convert exponential float numbers ala '23e13'" do
+            Puppet::Parser::Scope.number?("23e13").should == 23e13
+        end
+
+        it "should understand hexadecimal numbers" do
+            Puppet::Parser::Scope.number?("0x234").should == 0x234
+        end
+
+        it "should understand octal numbers" do
+            Puppet::Parser::Scope.number?("0755").should == 0755
+        end
+
+
+    end
+
 end

-- 
Puppet packaging for Debian



More information about the Pkg-puppet-devel mailing list