Module: Python::Syntax

Defined in:
lib/python/syntax.rb

Defined Under Namespace

Classes: Statement

Constant Summary collapse

Expression =
Class.new(Statement)
PyBoolizeError =

Exceptions possibly occurring when evaluating

Class.new(RuntimeError)
PyNameError =
Class.new(RuntimeError)
PyCallError =
Class.new(RuntimeError)
StatementList =

AST-elements of Statements


stmt(:stmts) do |env|
  @stmts.inject(nil) do |acc, stmt|
    stmt.eval(env)
  end
end
AssignIdentifier =
stmt(:name, :exp) do |env|
  env.set(@name, @exp.eval(env))
  nil
end
AssignAttr =
stmt(:receiver, :attrname, :exp) do |env|
  @receiver.eval(env).set_attr(@attrname, @exp.eval(env))
  nil
end
Def =
stmt(:name, :stat, :fix_param_names, [:rest_param_name]) do |env|
  entity = {:fix_param_names => @fix_param_names,
            :rest_param_name => @rest_param_name,
            :stat => @stat,
            :env => env.getlink}
  env.set(@name, Builtins::Func.make_instance(entity))
  nil
end
ClassDef =
stmt(:name, :stat, :base_exps) do |env|
  bases = @base_exps.map{|e| e.eval(env)}
  klassenv = ClassEnvironment.new(:parent => env)
  stat.eval(klassenv)
  klass = PyObject.new(klassenv.merge(:class => Builtins::Type, :bases => bases))
  env.set(@name, klass)
  nil
end
Return =
stmt([:exp]) do |env|
  res = if @exp then @exp.eval(env) else Builtins::None end
  throw :return, res
end
Apply =

AST-elements of Expressions


exp(:callee_exp, :arg_exps) do |env|
  @callee_exp.eval(env).call(*@arg_exps.map{|e| e.eval(env)})
end
AttrRef =
exp(:receiver, :attrname) do |env|
  @receiver.eval(env).get_attr(@attrname)
end
RefIdentifier =
exp(:name) do |env|
  if res = env.resolve(@name)
    res
  else
    raise PyNameError.new("Unbound variable: #{@name}")
  end
end
Conditional =
exp(:cond_exp, :true_exp, :false_exp) do |env|
  if Syntax.pytrue?(@cond_exp.eval(env))
    @true_exp.eval(env)
  else
    @false_exp.eval(env)
  end
end
UnaryOp =
exp(:op_name, :exp) do |env|
  @exp.eval(env).call_special_method(@op_name)
end
BinaryOp =
exp(:op_name, :left_exp, :right_exp) do |env|
  left = @left_exp.eval(env)
  right = @right_exp.eval(env)
  left.call_special_method(@op_name, right)
end
And =
exp(:left_exp, :right_exp) do |env|
  left = @left_exp.eval(env)
  if !Syntax.pytrue?(left)
    left
  else
    @right_exp.eval(env)
  end
end
Or =
exp(:left_exp, :right_exp) do |env|
  left = @left_exp.eval(env)
  if Syntax.pytrue?(left)
    left
  else
    @right_exp.eval(env)
  end
end
Not =
exp(:cond_exp) do |env|
  if Syntax.pytrue?(@cond_exp.eval(env))
    Builtins::False
  else
    Builtins::True
  end
end
LiteralObject =
exp(:object) do |env|
  @object
end

Class Method Summary collapse

Class Method Details

.define_element_type(base, *attrs, &eval_proc) ⇒ Object



48
49
50
51
52
53
54
# File 'lib/python/syntax.rb', line 48

def self.define_element_type(base, *attrs, &eval_proc)
  cls = Class.new(base)
  cls.send(:define_method, :attrs) { attrs }
  cls.send(:define_method, :eval_proc) { eval_proc }
  cls.send(:attr_reader, *attrs.flatten)
  return cls
end

.draw_syntax_tree(val, depth = 0) ⇒ Object



56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
# File 'lib/python/syntax.rb', line 56

def self.draw_syntax_tree(val, depth=0)
  case val
  when  Statement
    puts ("  " * depth) + "Node<#{val.class.name}>:"
    val.attrs.flatten.each do |attrname|
      puts ("  " * (depth + 1)) + "#{attrname}:"
      draw_syntax_tree(val.instance_variable_get("@#{attrname}".to_sym), depth + 2)
    end
  when Array
    val.each_with_index do |v, i|
      puts ("  " * (depth + 1)) + "[#{i}]"
      draw_syntax_tree(v, depth + 2)
    end
  else
    puts ("  " * (depth + 1)) + val.to_s
  end
end

.exp(*attrs, &eval) ⇒ Object



44
45
46
# File 'lib/python/syntax.rb', line 44

def self.exp(*attrs, &eval)
  define_element_type(Expression, *attrs, &eval)
end

.pytrue?(object) ⇒ Boolean

Returns:

  • (Boolean)


79
80
81
82
83
84
85
86
87
88
# File 'lib/python/syntax.rb', line 79

def self.pytrue?(object)
  boolized = object.call_special_method("__bool__")
  if boolized == Builtins::True
    return true
  elsif boolized == Builtins::False
    return false
  else
    raise PyBoolizeError.new
  end
end

.stmt(*attrs, &eval) ⇒ Object



40
41
42
# File 'lib/python/syntax.rb', line 40

def self.stmt(*attrs, &eval)
  define_element_type(Statement, *attrs, &eval)
end