diff options
author | luke <luke@980ebf18-57e1-0310-9a29-db15c13687c0> | 2005-09-21 17:39:43 +0000 |
---|---|---|
committer | luke <luke@980ebf18-57e1-0310-9a29-db15c13687c0> | 2005-09-21 17:39:43 +0000 |
commit | 5dc3cb04bebc79517ae5f64d1d3c652b6dfba7ea (patch) | |
tree | f14e075f078b7054ea69418756b5a28ceaed65ef /lib/puppet | |
parent | 0747b4c34ee0aa2ba4430021c1c0e676f71c20ac (diff) | |
download | puppet-5dc3cb04bebc79517ae5f64d1d3c652b6dfba7ea.tar.gz puppet-5dc3cb04bebc79517ae5f64d1d3c652b6dfba7ea.tar.xz puppet-5dc3cb04bebc79517ae5f64d1d3c652b6dfba7ea.zip |
Okay, significant change -- classes no longer accept arguments (which makes things simpler but encourages the user of global variables, which is bad), and classes are finally singletons, meaning they will only ever be evaluated for each node a single time. I still need to make nodes work correctly, but that is going to involve modifying the parsing system and a bit more
git-svn-id: https://reductivelabs.com/svn/puppet/trunk@694 980ebf18-57e1-0310-9a29-db15c13687c0
Diffstat (limited to 'lib/puppet')
-rw-r--r-- | lib/puppet/parser/ast.rb | 116 | ||||
-rw-r--r-- | lib/puppet/parser/grammar.ra | 20 | ||||
-rw-r--r-- | lib/puppet/parser/parser.rb | 285 | ||||
-rw-r--r-- | lib/puppet/parser/scope.rb | 252 |
4 files changed, 354 insertions, 319 deletions
diff --git a/lib/puppet/parser/ast.rb b/lib/puppet/parser/ast.rb index 6f916c6bd..a234bd165 100644 --- a/lib/puppet/parser/ast.rb +++ b/lib/puppet/parser/ast.rb @@ -1,14 +1,9 @@ -#/usr/bin/ruby - -# $Id$ -# vim: syntax=ruby +# the parent class for all of our syntactical objects -# the AST tree +require 'puppet' -# the parent class for all of our syntactical objects module Puppet module Parser - class ASTError < RuntimeError; end # The base class for all of the objects that make up the parse trees. # Handles things like file name, line #, and also does the initialization @@ -70,8 +65,8 @@ module Puppet puts caller end error = Puppet::DevError.new( - "Child of type %s failed: %s" % - [self.class, detail.to_s] + "Child of type %s failed with error %s: %s" % + [self.class, detail.class, detail.to_s] ) error.stack = caller raise error @@ -91,12 +86,14 @@ module Puppet # them. This is probably pretty inefficient and should likely be changed # at some point. def initialize(args) + @file = nil + @line = nil args.each { |param,value| method = param.to_s + "=" unless self.respond_to?(method) error = Puppet::DevError.new( "Invalid parameter %s to object class %s" % - [method,self.class.to_s] + [param,self.class.to_s] ) error.line = self.line error.file = self.file @@ -183,7 +180,7 @@ module Puppet # We basically always operate declaratively, and when we # do we need to evaluate the settor-like statements first. This # is basically variable and type-default declarations. - if scope.declarative + if scope.declarative? test = [ AST::VarDef, AST::TypeDefaults ] @@ -365,6 +362,10 @@ module Puppet # first, retrieve the defaults begin defaults = scope.lookupdefaults(objtype) + if defaults.length > 0 + Puppet.debug "Got defaults for %s: %s" % + [objtype,defaults.inspect] + end rescue => detail raise Puppet::DevError, "Could not lookup defaults for %s: %s" % @@ -429,8 +430,12 @@ module Puppet # just store it in our objectable if object.nil? begin - Puppet.debug("Setting object '%s' with arguments %s" % - [objname, hash.inspect]) + Puppet.debug( + ("Setting object '%s' " + + "in scope %s " + + "with arguments %s") % + [objname, scope.object_id, hash.inspect] + ) obj = scope.setobject( objtype, objname, @@ -888,7 +893,6 @@ module Puppet name = @name.safeevaluate(scope) value = @value.safeevaluate(scope) - Puppet.debug "setting %s to %s" % [name,value] begin scope.setvar(name,value) rescue Puppet::ParseError => except @@ -1077,41 +1081,33 @@ module Puppet def each if @parentclass - [@name,@args,@parentclass,@code].each { |child| yield child } + #[@name,@args,@parentclass,@code].each { |child| yield child } + [@name,@parentclass,@code].each { |child| yield child } else - [@name,@args,@code].each { |child| yield child } + #[@name,@args,@code].each { |child| yield child } + [@name,@code].each { |child| yield child } end end # Store our parse tree according to name. def evaluate(scope) name = @name.safeevaluate(scope) - args = @args.safeevaluate(scope) + #args = @args.safeevaluate(scope) + #:args => args, arghash = { :name => name, - :args => args, :code => @code } if @parentclass - parent = @parentclass.safeevaluate(scope) - else - parent = nil + arghash[:parentclass] = @parentclass.safeevaluate(scope) end #Puppet.debug("defining hostclass '%s' with arguments [%s]" % # [name,args]) begin - arghash = { - :name => name, - :args => args, - :code => @code - } - if parent - arghash[:parentclass] = parent - end scope.settype(name, HostClass.new(arghash) ) @@ -1134,10 +1130,10 @@ module Puppet end def tree(indent = 0) + #@args.tree(indent + 1), return [ @name.tree(indent + 1), ((@@indline * 4 * indent) + self.typewrap("class")), - @args.tree(indent + 1), @parentclass ? @parentclass.tree(indent + 1) : "", @code.tree(indent + 1), ].join("\n") @@ -1145,7 +1141,8 @@ module Puppet def to_s return "class %s(%s) inherits %s {\n%s }" % - [@name, @args, @parentclass, @code] + [@name, @parentclass, @code] + #[@name, @args, @parentclass, @code] end end @@ -1274,6 +1271,10 @@ module Puppet attr_accessor :parentclass def evaluate(scope,hash,objtype,objname) + if scope.lookupclass(@name) + Puppet.debug "%s class already evaluated" % @name + return nil + end if @parentclass begin parentobj = scope.lookuptype(@parentclass) @@ -1295,14 +1296,28 @@ module Puppet error.file = self.file raise error end - # FIXME I should only have _one_ instance of a given - # parent class + + # Verify that the parent and child are of the same type + unless parentobj.class == self.class + error = Puppet::ParseError.new( + "Class %s has incompatible parent type" % + [@name] + ) + error.file = self.file + error.line = self.line + raise error + end parentobj.safeevaluate(scope,hash,@parentclass,objname) end # just use the Component evaluate method, but change the type # to our own type - super(scope,hash,@name,objname) + retval = super(scope,hash,@name,objname) + + # Set the mark after we evaluate, so we don't record it but + # then encounter an error + scope.setclass(@name) + return retval end def initialize(hash) @@ -1317,36 +1332,17 @@ module Puppet attr_accessor :name, :args, :code, :parentclass def evaluate(scope,hash,objtype,objname) - if @parentclass - begin - parentobj = scope.lookuptype(@parentclass) - rescue Puppet::ParseError => except - except.line = self.line - except.file = self.file - raise except - rescue => detail - error = Puppet::ParseError.new(detail) - error.line = self.line - error.file = self.file - raise error - end - unless parentobj - error = Puppet::ParseError.new( - "Could not find parent '%s' of '%s'" % - [@parentclass,@name]) - error.line = self.line - error.file = self.file - raise error - end - parentobj.safeevaluate(scope,hash,objtype,objname) - end + scope = scope.newscope + scope.type = objtype + scope.name = objname + scope.nodescope = true - # just use the Component evaluate method, but change the type - # to our own type - super(scope,hash,@name,objname) + self.code.safeevaluate(scope) end end #--------------------------------------------------------------- end end end + +# $Id$ diff --git a/lib/puppet/parser/grammar.ra b/lib/puppet/parser/grammar.ra index 2b183539b..7b05433ce 100644 --- a/lib/puppet/parser/grammar.ra +++ b/lib/puppet/parser/grammar.ra @@ -117,7 +117,6 @@ object: name LBRACE objectinstances endsemi RBRACE { } | type LBRACE params endcomma RBRACE { # a template setting for a type if val[0].is_a?(AST::ASTArray) - Puppet.notice "invalid type" raise Puppet::ParseError, "Invalid type" end result = AST::TypeDefaults.new( @@ -448,22 +447,23 @@ definition: DEFINE NAME argumentlist LBRACE statements RBRACE { ) } -hostclass: CLASS NAME argumentlist parent LBRACE statements RBRACE { +#hostclass: CLASS NAME argumentlist parent LBRACE statements RBRACE { +hostclass: CLASS NAME parent LBRACE statements RBRACE { + #:args => val[2], args = { :name => AST::Name.new(:value => val[1], :line => @lexer.line), - :args => val[2], :file => @lexer.file, :line => @lexer.line, - :code => val[5] + :code => val[4] } # It'll be an ASTArray if we didn't get a parent - if val[3].is_a?(AST::Name) - args[:parentclass] = val[3] + if val[2].is_a?(AST::Name) + args[:parentclass] = val[2] end result = AST::ClassDef.new(args) } -nodedef: NODE names parent LBRACE statements RBRACE { +nodedef: NODE names LBRACE statements RBRACE { unless val[1].is_a?(AST::ASTArray) val[1] = AST::ASTArray.new( :line => val[1].line, @@ -477,9 +477,9 @@ nodedef: NODE names parent LBRACE statements RBRACE { :names => val[1], :code => val[4] } - if val[3].is_a?(AST::Name) - args[:parentclass] = val[2] - end + #if val[3].is_a?(AST::Name) + # args[:parentclass] = val[2] + #end result = AST::NodeDef.new(args) } diff --git a/lib/puppet/parser/parser.rb b/lib/puppet/parser/parser.rb index 2f0c4f10c..b636b7b37 100644 --- a/lib/puppet/parser/parser.rb +++ b/lib/puppet/parser/parser.rb @@ -31,7 +31,7 @@ module Puppet class Parser < Racc::Parser -module_eval <<'..end grammar.ra modeval..id68a1b36c80', 'grammar.ra', 606 +module_eval <<'..end grammar.ra modeval..idea8fcb8472', 'grammar.ra', 606 attr_writer :stack attr_reader :file @@ -135,7 +135,7 @@ end def string=(string) @lexer.string = string end -..end grammar.ra modeval..id68a1b36c80 +..end grammar.ra modeval..idea8fcb8472 ##### racc 1.4.4 generates ### @@ -205,8 +205,8 @@ racc_reduce_table = [ 1, 71, :_reduce_none, 2, 46, :_reduce_63, 6, 47, :_reduce_64, - 7, 48, :_reduce_65, - 6, 49, :_reduce_66, + 6, 48, :_reduce_65, + 5, 49, :_reduce_66, 1, 77, :_reduce_none, 2, 77, :_reduce_68, 0, 78, :_reduce_69, @@ -228,28 +228,28 @@ racc_reduce_table = [ racc_reduce_n = 85 -racc_shift_n = 145 +racc_shift_n = 143 racc_action_table = [ - 89, 123, 89, 72, 49, 101, 53, 112, 89, 6, - 89, 121, 92, 111, 54, 82, 89, 40, 89, 83, - 84, 134, 102, 83, 84, 122, 75, 105, 36, 106, + 89, 123, 89, 112, 134, 119, 83, 84, 89, 111, + 89, 54, 92, 74, 40, 102, 89, 75, 89, 121, + 103, 75, 72, 74, 71, 122, 45, 109, 36, 110, 36, 87, 88, 87, 88, 90, 36, 90, 36, 87, 88, 87, 88, 90, 36, 90, 36, 87, 88, 87, - 88, 90, 21, 90, 27, 28, 27, 28, 45, 109, - 110, 72, 113, 53, 74, 27, 28, 27, 28, 116, - 27, 28, 45, 119, 55, 81, 27, 28, 124, 31, - 45, 31, 6, 36, 127, 36, 3, 6, 3, 6, + 88, 90, 6, 90, 27, 28, 27, 28, 82, 100, + 113, 58, 83, 84, 55, 27, 28, 27, 28, 116, + 27, 28, 6, 101, 53, 21, 27, 28, 49, 31, + 45, 31, 45, 36, 127, 36, 3, 6, 3, 6, 31, 128, 31, 6, 36, 31, 36, 3, 6, 3, - 6, 31, 3, 60, 6, 36, 27, 28, 3, 6, - 41, 27, 28, 40, 39, 75, 27, 28, 136, 38, - 74, 27, 28, 139, 23, 22, 69, 21, 45, 49, + 6, 31, 3, 6, 6, 36, 27, 28, 3, 6, + 41, 27, 28, 40, 39, 81, 27, 28, 136, 38, + 23, 27, 28, 139, 22, 21, 45, 53, nil, nil, nil, 31, nil, nil, nil, 36, 31, 132, 3, 6, - 36, 31, nil, 3, 6, 36, 31, nil, 3, 6, - nil, 140, nil, 3, 6, 5, 8, nil, 12, 14, - nil, 17, nil, nil, nil, 3, 6, 143, 10, 5, + nil, 31, nil, 3, 62, 36, 31, nil, 3, 6, + 36, 138, nil, 3, 6, 5, 8, nil, 12, 14, + nil, 17, nil, nil, nil, 3, 6, 129, 10, 5, 8, nil, 12, 14, nil, 17, nil, nil, nil, 3, - 6, 144, 10, nil, nil, 5, 8, nil, 12, 14, + 6, 142, 10, nil, nil, 5, 8, nil, 12, 14, nil, 17, nil, nil, nil, 3, 6, nil, 10, 5, 8, nil, 12, 14, nil, 17, nil, nil, nil, 3, 6, nil, 10, 5, 8, nil, 12, 14, nil, 17, @@ -263,115 +263,115 @@ racc_action_table = [ nil, nil, nil, 3, 6, nil, 10 ] racc_action_check = [ - 135, 98, 92, 42, 23, 61, 64, 78, 96, 42, - 53, 96, 53, 78, 34, 52, 55, 34, 123, 52, - 52, 118, 67, 118, 118, 98, 68, 72, 135, 73, - 92, 135, 135, 92, 92, 135, 96, 92, 53, 96, - 96, 53, 53, 96, 55, 53, 123, 55, 55, 123, - 123, 55, 25, 123, 54, 54, 116, 116, 75, 76, - 77, 57, 80, 32, 60, 113, 113, 10, 10, 91, - 40, 40, 21, 95, 35, 50, 38, 38, 100, 54, - 101, 116, 17, 54, 103, 116, 54, 54, 116, 116, - 113, 104, 10, 49, 113, 40, 10, 113, 113, 10, - 10, 38, 40, 40, 112, 38, 85, 85, 38, 38, - 16, 74, 74, 15, 14, 47, 27, 27, 122, 12, - 45, 102, 102, 125, 8, 5, 41, 1, 139, 39, - nil, 85, nil, nil, nil, 85, 74, 114, 85, 85, - 74, 27, nil, 74, 74, 27, 102, nil, 27, 27, - nil, 129, nil, 102, 102, 114, 114, nil, 114, 114, - nil, 114, nil, nil, nil, 114, 114, 138, 114, 129, - 129, nil, 129, 129, nil, 129, nil, nil, nil, 129, - 129, 142, 129, nil, nil, 138, 138, nil, 138, 138, - nil, 138, nil, nil, nil, 138, 138, nil, 138, 142, - 142, nil, 142, 142, nil, 142, nil, nil, nil, 142, - 142, nil, 142, 0, 0, nil, 0, 0, nil, 0, - nil, nil, nil, 0, 0, nil, 0, 18, 18, nil, - 18, 18, nil, 18, nil, nil, nil, 18, 18, nil, - 18, 124, 124, nil, 124, 124, nil, 124, nil, nil, - nil, 124, 124, nil, 124, 81, 81, nil, 81, 81, - nil, 81, nil, nil, nil, 81, 81, nil, 81, 136, - 136, nil, 136, 136, nil, 136, nil, nil, nil, 136, - 136, nil, 136, 106, 106, nil, 106, 106, nil, 106, - nil, nil, nil, 106, 106, nil, 106 ] + 92, 98, 55, 78, 118, 95, 118, 118, 135, 78, + 53, 34, 53, 62, 34, 63, 96, 47, 123, 96, + 69, 70, 42, 45, 41, 98, 75, 76, 92, 77, + 55, 92, 92, 55, 55, 92, 135, 55, 53, 135, + 135, 53, 53, 135, 96, 53, 123, 96, 96, 123, + 123, 96, 42, 123, 54, 54, 116, 116, 52, 58, + 80, 39, 52, 52, 35, 113, 113, 10, 10, 91, + 103, 103, 49, 59, 32, 25, 85, 85, 23, 54, + 102, 116, 21, 54, 104, 116, 54, 54, 116, 116, + 113, 105, 10, 17, 113, 103, 10, 113, 113, 10, + 10, 85, 103, 103, 112, 85, 74, 74, 85, 85, + 16, 40, 40, 15, 14, 50, 27, 27, 122, 12, + 8, 38, 38, 125, 5, 1, 139, 66, nil, nil, + nil, 74, nil, nil, nil, 74, 40, 114, 74, 74, + nil, 27, nil, 40, 40, 27, 38, nil, 27, 27, + 38, 124, nil, 38, 38, 114, 114, nil, 114, 114, + nil, 114, nil, nil, nil, 114, 114, 106, 114, 124, + 124, nil, 124, 124, nil, 124, nil, nil, nil, 124, + 124, 141, 124, nil, nil, 106, 106, nil, 106, 106, + nil, 106, nil, nil, nil, 106, 106, nil, 106, 141, + 141, nil, 141, 141, nil, 141, nil, nil, nil, 141, + 141, nil, 141, 72, 72, nil, 72, 72, nil, 72, + nil, nil, nil, 72, 72, nil, 72, 101, 101, nil, + 101, 101, nil, 101, nil, nil, nil, 101, 101, nil, + 101, 18, 18, nil, 18, 18, nil, 18, nil, nil, + nil, 18, 18, nil, 18, 136, 136, nil, 136, 136, + nil, 136, nil, nil, nil, 136, 136, nil, 136, 81, + 81, nil, 81, 81, nil, 81, nil, nil, nil, 81, + 81, nil, 81, 0, 0, nil, 0, 0, nil, 0, + nil, nil, nil, 0, 0, nil, 0 ] racc_action_pointer = [ - 189, 122, nil, nil, nil, 122, nil, nil, 89, nil, - 65, nil, 107, nil, 79, 108, 110, 47, 203, nil, - nil, 37, nil, -10, nil, 47, nil, 114, nil, nil, - nil, nil, 50, nil, 12, 69, nil, nil, 74, 115, - 68, 126, -26, nil, nil, 112, nil, 106, nil, 58, - 70, nil, 11, 7, 52, 13, nil, 32, nil, nil, - 56, -28, nil, nil, -7, nil, nil, -14, 17, nil, - nil, nil, -8, 24, 109, 23, 53, 45, -2, nil, - 50, 231, nil, nil, nil, 104, nil, nil, nil, nil, - nil, 61, -1, nil, nil, 69, 5, nil, -8, nil, - 73, 45, 119, 78, 85, nil, 259, nil, nil, nil, - nil, nil, 69, 63, 131, nil, 54, nil, 15, nil, - nil, nil, 113, 15, 217, 114, nil, nil, nil, 145, - nil, nil, nil, nil, nil, -3, 245, nil, 161, 93, - nil, nil, 175, nil, nil ] + 259, 120, nil, nil, nil, 121, nil, nil, 85, nil, + 65, nil, 107, nil, 79, 108, 110, 58, 217, nil, + nil, 47, nil, 64, nil, 70, nil, 114, nil, nil, + nil, nil, 61, nil, 9, 59, nil, nil, 119, 32, + 109, 24, 17, nil, nil, 15, nil, 8, nil, 37, + 110, nil, 54, 7, 52, -1, nil, nil, 24, 68, + nil, nil, 5, -18, nil, nil, 114, nil, nil, -16, + 12, nil, 189, nil, 104, -9, 21, 14, -6, nil, + 48, 245, nil, nil, nil, 74, nil, nil, nil, nil, + nil, 61, -3, nil, nil, 1, 13, nil, -8, nil, + nil, 203, 45, 68, 78, 85, 161, nil, nil, nil, + nil, nil, 69, 63, 131, nil, 54, nil, -2, nil, + nil, nil, 113, 15, 145, 114, nil, nil, nil, nil, + nil, nil, nil, nil, nil, 5, 231, nil, nil, 91, + nil, 175, nil ] racc_action_default = [ -85, -85, -5, -20, -6, -85, -19, -7, -85, -8, -85, -9, -85, -10, -85, -85, -85, -85, -1, -2, -4, -28, -63, -69, -37, -36, -42, -85, -43, -34, -38, -79, -40, -41, -35, -85, -44, -39, -85, -69, - -28, -85, -69, -67, -3, -85, -29, -83, -70, -69, - -85, -32, -85, -85, -85, -85, -27, -69, -23, -15, - -19, -85, -21, -24, -25, -26, -22, -17, -83, 145, - -77, -68, -85, -85, -85, -84, -85, -85, -85, -73, + -28, -85, -85, -67, -3, -85, -29, -83, -70, -69, + -85, -32, -85, -85, -85, -85, -27, -77, -85, -85, + -23, -15, -19, -85, -21, -24, -25, -26, -22, -17, + -83, 143, -85, -68, -85, -84, -85, -85, -85, -73, -76, -85, -80, -81, -82, -85, -62, -59, -58, -60, -61, -85, -85, -52, -53, -85, -85, -47, -85, -50, - -85, -28, -18, -85, -85, -78, -85, -31, -30, -13, + -78, -85, -28, -18, -85, -85, -85, -31, -30, -13, -71, -72, -85, -85, -85, -33, -85, -55, -85, -45, - -48, -46, -85, -85, -85, -14, -16, -11, -12, -85, - -74, -75, -64, -57, -54, -85, -85, -51, -85, -85, - -66, -56, -85, -65, -49 ] + -48, -46, -85, -85, -85, -14, -16, -11, -12, -66, + -74, -75, -64, -57, -54, -85, -85, -51, -65, -85, + -56, -85, -49 ] racc_goto_table = [ - 18, 44, 35, 94, 37, 85, 99, 64, 25, 47, - 86, 108, 86, 79, 97, 50, 65, 103, 76, 51, - 63, 37, 62, 67, 59, 25, 34, 118, 68, 73, - 56, 57, 37, 43, 93, 96, 25, 42, 58, 104, - 52, 78, 117, 34, 100, 16, 95, 99, 37, 86, - nil, nil, 25, 86, 34, 120, 66, nil, 71, nil, - nil, nil, nil, nil, nil, 80, 107, nil, 37, 64, - 34, 135, 25, nil, 137, 108, 130, 115, 65, 37, - 86, 114, 63, 25, 62, 141, 126, 70, nil, 125, - 34, nil, 86, nil, 77, nil, nil, 44, nil, nil, - 58, 34, 70, nil, nil, 131, 129, 37, 133, nil, - 37, 25, 44, nil, 25, nil, nil, nil, 66, nil, - nil, 44, nil, nil, 138, 44, nil, nil, 80, 34, - nil, nil, 34, nil, nil, nil, 142 ] + 18, 44, 37, 25, 94, 108, 86, 35, 86, 34, + 47, 99, 67, 97, 85, 76, 43, 118, 48, 37, + 25, 104, 66, 93, 51, 69, 34, 65, 96, 70, + 37, 25, 61, 60, 57, 56, 64, 34, 105, 68, + 79, 73, 50, 117, 77, 86, 37, 25, 80, 86, + 59, 95, 99, 34, 120, 42, 52, 78, 16, nil, + nil, nil, nil, nil, nil, nil, 37, 25, nil, 108, + nil, 107, 106, 34, nil, 67, 86, 37, 25, 137, + 135, 114, 115, nil, 34, 66, 140, nil, 86, 44, + 65, 125, nil, nil, nil, 126, 60, 44, nil, 64, + nil, 124, 68, 130, nil, 37, 25, 44, 37, 25, + 131, 80, 34, 133, nil, 34, nil, nil, nil, nil, + nil, nil, nil, nil, 44, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 141 ] racc_goto_check = [ - 2, 3, 23, 34, 4, 26, 32, 21, 16, 14, - 27, 24, 27, 41, 30, 36, 22, 13, 15, 23, - 20, 4, 19, 12, 17, 16, 11, 35, 14, 37, - 23, 36, 4, 11, 33, 29, 16, 38, 16, 15, - 25, 40, 34, 11, 37, 1, 23, 32, 4, 27, - nil, nil, 16, 27, 11, 30, 11, nil, 11, nil, - nil, nil, nil, nil, nil, 11, 23, nil, 4, 21, - 11, 26, 16, nil, 32, 24, 41, 23, 22, 4, - 27, 2, 20, 16, 19, 34, 17, 39, nil, 14, - 11, nil, 27, nil, 39, nil, nil, 3, nil, nil, - 16, 11, 39, nil, nil, 23, 2, 4, 23, nil, - 4, 16, 3, nil, 16, nil, nil, nil, 11, nil, - nil, 3, nil, nil, 2, 3, nil, nil, 11, 11, - nil, nil, 11, nil, nil, nil, 2 ] + 2, 3, 4, 16, 34, 24, 27, 23, 27, 11, + 14, 32, 22, 30, 26, 15, 11, 35, 39, 4, + 16, 13, 21, 33, 23, 12, 11, 20, 29, 14, + 4, 16, 17, 16, 39, 23, 19, 11, 15, 11, + 41, 11, 36, 34, 39, 27, 4, 16, 11, 27, + 37, 23, 32, 11, 30, 38, 25, 40, 1, nil, + nil, nil, nil, nil, nil, nil, 4, 16, nil, 24, + nil, 23, 2, 11, nil, 22, 27, 4, 16, 32, + 26, 2, 23, nil, 11, 21, 34, nil, 27, 3, + 20, 14, nil, nil, nil, 17, 16, 3, nil, 19, + nil, 2, 11, 41, nil, 4, 16, 3, 4, 16, + 23, 11, 11, 23, nil, 11, nil, nil, nil, nil, + nil, nil, nil, nil, 3, nil, nil, nil, nil, nil, + nil, nil, nil, nil, nil, nil, 2 ] racc_goto_pointer = [ - nil, 45, 0, -17, -6, nil, nil, nil, nil, nil, - nil, 16, -17, -50, -12, -29, -2, -16, nil, -18, - -20, -33, -24, -8, -64, 13, -47, -43, nil, -20, - -41, nil, -49, -19, -50, -65, -8, -13, 20, 45, - -8, -36 ] + nil, 58, 0, -17, -8, nil, nil, nil, nil, nil, + nil, -1, -15, -48, -11, -32, -7, -8, nil, -4, + -13, -18, -28, -3, -70, 29, -38, -47, nil, -27, + -42, nil, -44, -30, -49, -75, 19, 11, 38, -5, + 8, -9 ] racc_goto_default = [ nil, nil, nil, 19, 20, 2, 4, 7, 9, 11, - 13, 15, nil, nil, nil, nil, 1, nil, 61, 29, + 13, 15, nil, nil, nil, nil, 1, nil, 63, 29, 30, 32, 33, nil, 46, nil, nil, 24, 26, nil, - nil, 98, 91, nil, nil, nil, nil, nil, nil, 48, + nil, 98, 91, nil, nil, nil, nil, nil, nil, nil, nil, nil ] racc_token_table = { @@ -646,11 +646,10 @@ module_eval <<'.,.,', 'grammar.ra', 117 end .,., -module_eval <<'.,.,', 'grammar.ra', 130 +module_eval <<'.,.,', 'grammar.ra', 129 def _reduce_13( val, _values, result ) # a template setting for a type if val[0].is_a?(AST::ASTArray) - Puppet.notice "invalid type" raise Puppet::ParseError, "Invalid type" end result = AST::TypeDefaults.new( @@ -664,7 +663,7 @@ module_eval <<'.,.,', 'grammar.ra', 130 end .,., -module_eval <<'.,.,', 'grammar.ra', 138 +module_eval <<'.,.,', 'grammar.ra', 137 def _reduce_14( val, _values, result ) result = AST::ObjectInst.new( :line => @lexer.line, @@ -677,7 +676,7 @@ module_eval <<'.,.,', 'grammar.ra', 138 # reduce 15 omitted -module_eval <<'.,.,', 'grammar.ra', 152 +module_eval <<'.,.,', 'grammar.ra', 151 def _reduce_16( val, _values, result ) if val[0].is_a?(AST::ObjectInst) result = AST::ASTArray.new( @@ -697,7 +696,7 @@ module_eval <<'.,.,', 'grammar.ra', 152 # reduce 18 omitted -module_eval <<'.,.,', 'grammar.ra', 163 +module_eval <<'.,.,', 'grammar.ra', 162 def _reduce_19( val, _values, result ) result = AST::Name.new( :line => @lexer.line, @@ -708,7 +707,7 @@ module_eval <<'.,.,', 'grammar.ra', 163 end .,., -module_eval <<'.,.,', 'grammar.ra', 171 +module_eval <<'.,.,', 'grammar.ra', 170 def _reduce_20( val, _values, result ) result = AST::Type.new( :line => @lexer.line, @@ -731,7 +730,7 @@ module_eval <<'.,.,', 'grammar.ra', 171 # reduce 26 omitted -module_eval <<'.,.,', 'grammar.ra', 194 +module_eval <<'.,.,', 'grammar.ra', 193 def _reduce_27( val, _values, result ) # this is distinct from referencing a variable variable = AST::Name.new( @@ -750,7 +749,7 @@ module_eval <<'.,.,', 'grammar.ra', 194 end .,., -module_eval <<'.,.,', 'grammar.ra', 203 +module_eval <<'.,.,', 'grammar.ra', 202 def _reduce_28( val, _values, result ) result = AST::ASTArray.new( :line => @lexer.line, @@ -761,14 +760,14 @@ module_eval <<'.,.,', 'grammar.ra', 203 end .,., -module_eval <<'.,.,', 'grammar.ra', 203 +module_eval <<'.,.,', 'grammar.ra', 202 def _reduce_29( val, _values, result ) result = val[0] result end .,., -module_eval <<'.,.,', 'grammar.ra', 216 +module_eval <<'.,.,', 'grammar.ra', 215 def _reduce_30( val, _values, result ) if val[0].is_a?(AST::ASTArray) val[0].push(val[2]) @@ -784,7 +783,7 @@ module_eval <<'.,.,', 'grammar.ra', 216 end .,., -module_eval <<'.,.,', 'grammar.ra', 231 +module_eval <<'.,.,', 'grammar.ra', 230 def _reduce_31( val, _values, result ) leaf = AST::String.new( :line => @lexer.line, @@ -804,7 +803,7 @@ module_eval <<'.,.,', 'grammar.ra', 231 # reduce 32 omitted -module_eval <<'.,.,', 'grammar.ra', 244 +module_eval <<'.,.,', 'grammar.ra', 243 def _reduce_33( val, _values, result ) if val[0].is_a?(AST::ASTArray) result = val[0].push(val[2]) @@ -837,7 +836,7 @@ module_eval <<'.,.,', 'grammar.ra', 244 # reduce 42 omitted -module_eval <<'.,.,', 'grammar.ra', 262 +module_eval <<'.,.,', 'grammar.ra', 261 def _reduce_43( val, _values, result ) result = AST::String.new( :line => @lexer.line, @@ -848,7 +847,7 @@ module_eval <<'.,.,', 'grammar.ra', 262 end .,., -module_eval <<'.,.,', 'grammar.ra', 270 +module_eval <<'.,.,', 'grammar.ra', 269 def _reduce_44( val, _values, result ) result = AST::Boolean.new( :line => @lexer.line, @@ -859,7 +858,7 @@ module_eval <<'.,.,', 'grammar.ra', 270 end .,., -module_eval <<'.,.,', 'grammar.ra', 280 +module_eval <<'.,.,', 'grammar.ra', 279 def _reduce_45( val, _values, result ) result = AST::ObjectRef.new( :pin => '[]', @@ -872,7 +871,7 @@ module_eval <<'.,.,', 'grammar.ra', 280 end .,., -module_eval <<'.,.,', 'grammar.ra', 297 +module_eval <<'.,.,', 'grammar.ra', 296 def _reduce_46( val, _values, result ) options = val[3] unless options.is_a?(AST::ASTArray) @@ -894,7 +893,7 @@ module_eval <<'.,.,', 'grammar.ra', 297 # reduce 47 omitted -module_eval <<'.,.,', 'grammar.ra', 311 +module_eval <<'.,.,', 'grammar.ra', 310 def _reduce_48( val, _values, result ) if val[0].is_a?(AST::ASTArray) val[0].push val[1] @@ -910,7 +909,7 @@ module_eval <<'.,.,', 'grammar.ra', 311 end .,., -module_eval <<'.,.,', 'grammar.ra', 321 +module_eval <<'.,.,', 'grammar.ra', 320 def _reduce_49( val, _values, result ) result = AST::CaseOpt.new( :pin => ":", @@ -925,7 +924,7 @@ module_eval <<'.,.,', 'grammar.ra', 321 # reduce 50 omitted -module_eval <<'.,.,', 'grammar.ra', 335 +module_eval <<'.,.,', 'grammar.ra', 334 def _reduce_51( val, _values, result ) if val[0].is_a?(AST::ASTArray) val[0].push(val[2]) @@ -941,7 +940,7 @@ module_eval <<'.,.,', 'grammar.ra', 335 end .,., -module_eval <<'.,.,', 'grammar.ra', 345 +module_eval <<'.,.,', 'grammar.ra', 344 def _reduce_52( val, _values, result ) result = AST::Selector.new( :pin => "?", @@ -956,7 +955,7 @@ module_eval <<'.,.,', 'grammar.ra', 345 # reduce 53 omitted -module_eval <<'.,.,', 'grammar.ra', 347 +module_eval <<'.,.,', 'grammar.ra', 346 def _reduce_54( val, _values, result ) result = val[1] result @@ -965,7 +964,7 @@ module_eval <<'.,.,', 'grammar.ra', 347 # reduce 55 omitted -module_eval <<'.,.,', 'grammar.ra', 362 +module_eval <<'.,.,', 'grammar.ra', 361 def _reduce_56( val, _values, result ) if val[0].is_a?(AST::ASTArray) val[0].push(val[2]) @@ -981,7 +980,7 @@ module_eval <<'.,.,', 'grammar.ra', 362 end .,., -module_eval <<'.,.,', 'grammar.ra', 372 +module_eval <<'.,.,', 'grammar.ra', 371 def _reduce_57( val, _values, result ) result = AST::ObjectParam.new( :pin => "=>", @@ -994,7 +993,7 @@ module_eval <<'.,.,', 'grammar.ra', 372 end .,., -module_eval <<'.,.,', 'grammar.ra', 380 +module_eval <<'.,.,', 'grammar.ra', 379 def _reduce_58( val, _values, result ) result = AST::String.new( :line => @lexer.line, @@ -1005,7 +1004,7 @@ module_eval <<'.,.,', 'grammar.ra', 380 end .,., -module_eval <<'.,.,', 'grammar.ra', 387 +module_eval <<'.,.,', 'grammar.ra', 386 def _reduce_59( val, _values, result ) result = AST::String.new( :line => @lexer.line, @@ -1016,7 +1015,7 @@ module_eval <<'.,.,', 'grammar.ra', 387 end .,., -module_eval <<'.,.,', 'grammar.ra', 394 +module_eval <<'.,.,', 'grammar.ra', 393 def _reduce_60( val, _values, result ) result = AST::String.new( :line => @lexer.line, @@ -1027,7 +1026,7 @@ module_eval <<'.,.,', 'grammar.ra', 394 end .,., -module_eval <<'.,.,', 'grammar.ra', 401 +module_eval <<'.,.,', 'grammar.ra', 400 def _reduce_61( val, _values, result ) result = AST::Default.new( :line => @lexer.line, @@ -1040,7 +1039,7 @@ module_eval <<'.,.,', 'grammar.ra', 401 # reduce 62 omitted -module_eval <<'.,.,', 'grammar.ra', 439 +module_eval <<'.,.,', 'grammar.ra', 438 def _reduce_63( val, _values, result ) # importing files # yuk, i hate keywords @@ -1080,7 +1079,7 @@ module_eval <<'.,.,', 'grammar.ra', 439 end .,., -module_eval <<'.,.,', 'grammar.ra', 449 +module_eval <<'.,.,', 'grammar.ra', 448 def _reduce_64( val, _values, result ) result = AST::CompDef.new( :name => AST::Name.new(:value => val[1], :line => @lexer.line), @@ -1095,16 +1094,16 @@ module_eval <<'.,.,', 'grammar.ra', 449 module_eval <<'.,.,', 'grammar.ra', 464 def _reduce_65( val, _values, result ) + #:args => val[2], args = { :name => AST::Name.new(:value => val[1], :line => @lexer.line), - :args => val[2], :file => @lexer.file, :line => @lexer.line, - :code => val[5] + :code => val[4] } # It'll be an ASTArray if we didn't get a parent - if val[3].is_a?(AST::Name) - args[:parentclass] = val[3] + if val[2].is_a?(AST::Name) + args[:parentclass] = val[2] end result = AST::ClassDef.new(args) result @@ -1126,9 +1125,9 @@ module_eval <<'.,.,', 'grammar.ra', 484 :names => val[1], :code => val[4] } - if val[3].is_a?(AST::Name) - args[:parentclass] = val[2] - end + #if val[3].is_a?(AST::Name) + # args[:parentclass] = val[2] + #end result = AST::NodeDef.new(args) result end diff --git a/lib/puppet/parser/scope.rb b/lib/puppet/parser/scope.rb index 4779fabe7..37e5c39b7 100644 --- a/lib/puppet/parser/scope.rb +++ b/lib/puppet/parser/scope.rb @@ -1,66 +1,71 @@ -#!/usr/local/bin/ruby -w - -# $Id$ - -# the interpreter -# -# this builds our virtual pinball machine, into which we'll place our host-specific -# information and out of which we'll receive our host-specific configuration +# The scope class, which handles storing and retrieving variables and types and +# such. require 'puppet/transportable' module Puppet module Parser - class ScopeError < RuntimeError - attr_accessor :line, :file - end - #--------------------------------------------------------------- class Scope - - attr_accessor :symtable, :objectable, :parent, :level, :interp + include Enumerable + attr_accessor :parent, :level, :interp attr_accessor :name, :type - # i don't really know how to deal with a global scope yet, so - # i'm leaving it disabled - @@global = nil - + # The global host table. This will likely be changed to be scoped, + # eventually, but for now it's not. @@hosttable = {} - @@settingtable = [] + + # Whether we behave declaratively. Note that it's a class variable, + # so all scopes behave the same. @@declarative = true - #------------------------------------------------------------ + # Retrieve and set the declarative setting. def Scope.declarative return @@declarative end - #------------------------------------------------------------ - #------------------------------------------------------------ def Scope.declarative=(val) @@declarative = val end - #------------------------------------------------------------ - #------------------------------------------------------------ - def Scope.global - return @@global - end - #------------------------------------------------------------ - - #------------------------------------------------------------ + # Create a new child scope. def child=(scope) @children.push(scope) end - #------------------------------------------------------------ - #------------------------------------------------------------ - def declarative - return @@declarative + # Test whether a given scope is declarative. Even though it's + # a global value, the calling objects don't need to know that. + def declarative? + @@declarative end - #------------------------------------------------------------ - #------------------------------------------------------------ + # Is this scope associated with being a node? The answer determines + # whether we store class instances here + def nodescope? + @nodescope + end + + def nodescope=(bool) + @nodescope = bool + end + + # Are we the top scope? + def topscope? + @level == 1 + end + + # Yield each child scope in turn + def each + @children.each { |child| + yield child + } + end + + # Initialize our new scope. Defaults to having no parent and to + # being declarative. def initialize(parent = nil, declarative = true) @parent = parent + @nodescope = false + if @parent.nil? @level = 1 @@declarative = declarative @@ -70,16 +75,28 @@ module Puppet @interp = @parent.interp end + # Our child scopes @children = [] + # The symbol table for this scope @symtable = Hash.new(nil) + + # The type table for this scope @typetable = Hash.new(nil) - # the defaultstable is a hash of hashes + # The table for storing class singletons. This will only actually + # be used by top scopes and node scopes. + @classtable = Hash.new(nil) + + # All of the defaults set for types. It's a hash of hashes, + # with the first key being the type, then the second key being + # the parameter. @defaultstable = Hash.new { |dhash,type| dhash[type] = Hash.new(nil) } + # The object table is similar, but it is actually a hash of hashes + # where the innermost objects are TransObject instances. @objectable = Hash.new { |typehash,typekey| #hash[key] = TransObject.new(key) typehash[typekey] = Hash.new { |namehash, namekey| @@ -93,6 +110,8 @@ module Puppet namehash[namekey] } } + + # Map the names to the tables. @map = { "variable" => @symtable, "type" => @typetable, @@ -100,15 +119,10 @@ module Puppet "defaults" => @defaultstable } end - #------------------------------------------------------------ - - #------------------------------------------------------------ - # this method just abstracts the upwards-recursive nature of - # name resolution - # because different tables are different depths (e.g., flat, or - # hash of hashes), we pass in a code snippet that gets passed - # the table. It is assumed that the code snippet already has - # the name in it + + # This method abstracts recursive searching. It accepts the type + # of search being done and then either a literal key to search for or + # a Proc instance to do the searching. def lookup(type,sub) table = @map[type] if table.nil? @@ -130,9 +144,21 @@ module Puppet return :undefined end end - #------------------------------------------------------------ - #------------------------------------------------------------ + # Look up a given class. This enables us to make sure classes are + # singletons + def lookupclass(klass) + if self.nodescope? or self.topscope? + return @classtable[klass] + else + unless @parent + raise Puppet::DevError, "Not top scope but not parent defined" + end + return @parent.lookupclass(klass) + end + end + + # Look up hosts from the global table. def lookuphost(name) if @@hosttable.include?(name) return @@hosttable[name] @@ -140,15 +166,14 @@ module Puppet return nil end end - #------------------------------------------------------------ - #------------------------------------------------------------ - # collect all of the defaults set at any higher scopes - # this is a different type of lookup because it's additive -- + # Collect all of the defaults set at any higher scopes. + # This is a different type of lookup because it's additive -- # it collects all of the defaults, with defaults in closer scopes - # overriding those in later scopes + # overriding those in later scopes. def lookupdefaults(type) values = {} + # first collect the values from the parents unless @parent.nil? @parent.lookupdefaults(type).each { |var,value| @@ -163,13 +188,12 @@ module Puppet values[var] = value } end - Puppet.debug "Got defaults for %s: %s" % - [type,values.inspect] + #Puppet.debug "Got defaults for %s: %s" % + # [type,values.inspect] return values end - #------------------------------------------------------------ - #------------------------------------------------------------ + # Look up a defined type. def lookuptype(name) Puppet.debug "Looking up type %s" % name value = self.lookup("type",name) @@ -180,31 +204,31 @@ module Puppet return value end end - #------------------------------------------------------------ - #------------------------------------------------------------ - # slightly different, because we're looking through a hash of hashes + # Look up an object by name and type. def lookupobject(name,type) - Puppet.debug "Looking up object %s of type %s" % [name, type] - sub = proc { |table| - if table.include?(type) - if type[type].include?(name) - type[type][name] + Puppet.debug "Looking up object %s of type %s in level %s" % + [name, type, @level] + unless defined? @@objectsearch + @@objectsearch = proc { |table| + if table.include?(type) + if table[type].include?(name) + table[type][name] + end + else + nil end - else - nil - end - } - value = self.lookup("object",sub) + } + end + value = self.lookup("object",@@objectsearch) if value == :undefined return nil else return value end end - #------------------------------------------------------------ - #------------------------------------------------------------ + # Look up a variable. The simplest value search we do. def lookupvar(name) Puppet.debug "Looking up variable %s" % name value = self.lookup("variable", name) @@ -219,16 +243,25 @@ module Puppet return value end end - #------------------------------------------------------------ - #------------------------------------------------------------ + # Create a new scope. def newscope Puppet.debug "Creating new scope, level %s" % [self.level + 1] return Puppet::Parser::Scope.new(self) end - #------------------------------------------------------------ - #------------------------------------------------------------ + # Store the fact that we've evaluated a given class. + # FIXME Shouldn't setclass actually store the code, not just a boolean? + def setclass(klass) + if self.nodescope? or self.topscope? + @classtable[klass] = true + else + @parent.setclass(klass) + end + end + + # Set defaults for a type. The typename should already be downcased, + # so that the syntax is isolated. def setdefaults(type,params) table = @defaultstable[type] @@ -259,23 +292,31 @@ module Puppet table[ary[0]] = ary[1] } end - #------------------------------------------------------------ - #------------------------------------------------------------ + # Store a host in the global table. def sethost(name,host) - @@hosttable[name] = host + if @@hosttable.include?(name) + str = "Host %s is already defined" % name + if @@hosttable[name].file + str += " in file %s" % @@hosttable[name].file + end + if @@hosttable[name].line + str += " on line %s" % @@hosttable[name].line + end + raise Puppet::ParseError, + "Host %s is already defined" % name + else + @@hosttable[name] = host + end end - #------------------------------------------------------------ - #------------------------------------------------------------ + # Define our type. def settype(name,ltype) @typetable[name] = ltype end - #------------------------------------------------------------ - #------------------------------------------------------------ - # when we have an 'eval' function, we should do that instead - # for now, we only support variables in strings + # Return an interpolated string. + # FIXME We do not yet support a non-interpolated string. def strinterp(string) newstring = string.dup regex = Regexp.new('\$\{(\w+)\}|\$(\w+)') @@ -293,14 +334,12 @@ module Puppet #Puppet.debug("result is '%s'" % newstring) return newstring end - #------------------------------------------------------------ - #------------------------------------------------------------ - # this is kind of quirky, because it doesn't differentiate between - # creating a new object and adding params to an existing object - # it doesn't solve the real problem, though: cases like file recursion, + # This is kind of quirky, because it doesn't differentiate between + # creating a new object and adding params to an existing object. + # It doesn't solve the real problem, though: cases like file recursion, # where one statement explicitly modifies an object, and another - # statement modifies it because of recursion + # statement modifies it because of recursion. def setobject(type, name, params, file, line) obj = self.lookupobject(name,type) if obj == :undefined or obj.nil? @@ -321,9 +360,10 @@ module Puppet } return obj end - #------------------------------------------------------------ - #------------------------------------------------------------ + # Set a variable in the current scope. This will override settings + # in scopes above, but will not allow variables in the current scope + # to be reassigned if we're declarative (which is the default). def setvar(name,value) Puppet.debug "Setting %s to '%s' at level %s" % [name.inspect,value,self.level] @@ -340,30 +380,30 @@ module Puppet @symtable[name] = value end end - #------------------------------------------------------------ - #------------------------------------------------------------ - # I'm pretty sure this method could be obviated, but it doesn't - # really seem worth it + # Convert our scope to a list of Transportable objects. def to_trans Puppet.debug "Translating scope %s at level %s" % [self.object_id,self.level] results = [] + # Iterate across our child scopes and call to_trans on them @children.each { |child| - Puppet.notice "Transing child of type %s" % child.class if child.is_a?(Scope) cresult = child.to_trans Puppet.debug "Got %s from scope %s" % [cresult.class,child.object_id] - # get rid of the arrayness + # Scopes normally result in a TransBucket, but they could + # also result in a normal array; if that happens, get rid + # of the array. unless cresult.is_a?(TransBucket) cresult.each { |result| results.push(result) } else + # Otherwise, just add it to our list of results. results.push(cresult) end elsif child.is_a?(TransObject) @@ -377,15 +417,15 @@ module Puppet raise error end } + + # Get rid of any nil objects. results = results.reject { |child| - # if a scope didn't result in any objects, we get some nils - # just get rid of them child.nil? } - # if we have a name and type, then make a TransBucket, which - # becomes a component - # else, just stack all of the objects into the current bucket + # If we have a name and type, then make a TransBucket, which + # becomes a component. + # Else, just stack all of the objects into the current bucket. if defined? @name bucket = TransBucket.new bucket.name = @name @@ -424,8 +464,8 @@ module Puppet return results end end - #------------------------------------------------------------ end - #--------------------------------------------------------------- end end + +# $Id$ |