summaryrefslogtreecommitdiffstats
path: root/lib/puppet
diff options
context:
space:
mode:
authorBrice Figureau <brice-puppet@daysofwonder.com>2008-09-26 22:54:42 +0200
committerBrice Figureau <brice@daysofwonder.com>2008-09-30 17:22:07 +0200
commitcfa230a2d7b0c5e57cc0379785bd2025520f1c35 (patch)
tree046bc7c55a6a1a8ed9b36c5371a3901a89a779c4 /lib/puppet
parent850e0baf0fbe321f14d4b9d913ce7dea39c9aa27 (diff)
downloadpuppet-cfa230a2d7b0c5e57cc0379785bd2025520f1c35.tar.gz
puppet-cfa230a2d7b0c5e57cc0379785bd2025520f1c35.tar.xz
puppet-cfa230a2d7b0c5e57cc0379785bd2025520f1c35.zip
Add arithmetic operators to AST
This changeset adds +,-,/,*,<< and >> computation and AST parse nodes.
Diffstat (limited to 'lib/puppet')
-rw-r--r--lib/puppet/parser/ast.rb2
-rw-r--r--lib/puppet/parser/ast/arithmetic_operator.rb41
-rw-r--r--lib/puppet/parser/ast/minus.rb23
-rw-r--r--lib/puppet/parser/scope.rb23
4 files changed, 89 insertions, 0 deletions
diff --git a/lib/puppet/parser/ast.rb b/lib/puppet/parser/ast.rb
index 572771201..5aa9f528a 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/arithmetic_operator.rb b/lib/puppet/parser/ast/arithmetic_operator.rb
new file mode 100644
index 000000000..8d9cef86a
--- /dev/null
+++ b/lib/puppet/parser/ast/arithmetic_operator.rb
@@ -0,0 +1,41 @@
+require 'puppet'
+require 'puppet/parser/ast/branch'
+
+class Puppet::Parser::AST
+ class ArithmeticOperator < AST::Branch
+
+ attr_accessor :operator, :lval, :rval
+
+ # Iterate across all of our children.
+ def each
+ [@lval,@rval,@operator].each { |child| yield child }
+ end
+
+ # Returns a boolean which is the result of the boolean operation
+ # of lval and rval operands
+ 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)
+ 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 arithmetic operator %s" % @operator
+ end
+ end
+ end
+end
diff --git a/lib/puppet/parser/ast/minus.rb b/lib/puppet/parser/ast/minus.rb
new file mode 100644
index 000000000..b0779a8ee
--- /dev/null
+++ b/lib/puppet/parser/ast/minus.rb
@@ -0,0 +1,23 @@
+require 'puppet'
+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 Minus < AST::Branch
+ attr_accessor :value
+
+ def each
+ yield @value
+ end
+
+ def evaluate(scope)
+ val = @value.safeevaluate(scope)
+ 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 1ff998d96..4acdf41c9 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)