comparison graal/com.oracle.truffle.ruby.parser/src/com/oracle/truffle/ruby/parser/ModuleTranslator.java @ 13514:0fbee3eb71f0

Ruby: import project.
author Chris Seaton <chris.seaton@oracle.com>
date Mon, 06 Jan 2014 17:12:09 +0000
parents
children 232eb6708943
comparison
equal deleted inserted replaced
13513:64a23ce736a0 13514:0fbee3eb71f0
1 /*
2 * Copyright (c) 2013 Oracle and/or its affiliates. All rights reserved. This
3 * code is released under a tri EPL/GPL/LGPL license. You can use it,
4 * redistribute it and/or modify it under the terms of the:
5 *
6 * Eclipse Public License version 1.0
7 * GNU General Public License version 2
8 * GNU Lesser General Public License version 2.1
9 */
10 package com.oracle.truffle.ruby.parser;
11
12 import com.oracle.truffle.api.*;
13 import com.oracle.truffle.api.nodes.*;
14 import com.oracle.truffle.ruby.nodes.*;
15 import com.oracle.truffle.ruby.nodes.constants.*;
16 import com.oracle.truffle.ruby.nodes.control.*;
17 import com.oracle.truffle.ruby.nodes.literal.*;
18 import com.oracle.truffle.ruby.nodes.methods.*;
19 import com.oracle.truffle.ruby.nodes.objects.*;
20 import com.oracle.truffle.ruby.runtime.*;
21 import com.oracle.truffle.ruby.runtime.methods.*;
22
23 /**
24 * Translates module and class nodes.
25 * <p>
26 * In Ruby, a module or class definition is somewhat like a method. It has a local scope and a value
27 * for self, which is the module or class object that is being defined. Therefore for a module or
28 * class definition we translate into a special method. We run that method with self set to be the
29 * newly allocated module or class. We then have to treat at least method and constant definitions
30 * differently.
31 */
32 class ModuleTranslator extends Translator {
33
34 public ModuleTranslator(RubyContext context, Translator parent, TranslatorEnvironment environment, Source source) {
35 super(context, parent, environment, source);
36 }
37
38 public MethodDefinitionNode compileClassNode(org.jrubyparser.SourcePosition sourcePosition, String name, org.jrubyparser.ast.Node bodyNode) {
39 final SourceSection sourceSection = translate(sourcePosition);
40
41 environment.addMethodDeclarationSlots();
42
43 final String methodName = "(" + name + "-def" + ")";
44 environment.setMethodName(methodName);
45
46 RubyNode body;
47
48 if (bodyNode != null) {
49 body = (RubyNode) bodyNode.accept(this);
50 } else {
51 body = new NilNode(context, sourceSection);
52 }
53
54 if (environment.getFlipFlopStates().size() > 0) {
55 body = new SequenceNode(context, sourceSection, initFlipFlopStates(sourceSection), body);
56 }
57
58 body = new CatchReturnNode(context, sourceSection, body, environment.getReturnID());
59
60 final RubyRootNode pristineRootNode = new RubyRootNode(sourceSection, methodName, body);
61
62 final CallTarget callTarget = Truffle.getRuntime().createCallTarget(NodeUtil.cloneNode(pristineRootNode), environment.getFrameDescriptor());
63
64 return new MethodDefinitionNode(context, sourceSection, methodName, environment.getUniqueMethodIdentifier(), environment.getFrameDescriptor(), environment.needsDeclarationFrame(),
65 pristineRootNode, callTarget);
66 }
67
68 @Override
69 public Object visitConstDeclNode(org.jrubyparser.ast.ConstDeclNode node) {
70 final SourceSection sourceSection = translate(node.getPosition());
71
72 final SelfNode selfNode = new SelfNode(context, sourceSection);
73
74 return new WriteConstantNode(context, sourceSection, node.getName(), selfNode, (RubyNode) node.getValue().accept(this));
75 }
76
77 @Override
78 public Object visitConstNode(org.jrubyparser.ast.ConstNode node) {
79 final SourceSection sourceSection = translate(node.getPosition());
80
81 final SelfNode selfNode = new SelfNode(context, sourceSection);
82
83 return new UninitializedReadConstantNode(context, sourceSection, node.getName(), selfNode);
84 }
85
86 @Override
87 public Object visitDefnNode(org.jrubyparser.ast.DefnNode node) {
88 /*
89 * The top-level translator puts methods into Object. We put ours into the self, which is
90 * the class being defined.
91 */
92
93 final TranslatorEnvironment newEnvironment = new TranslatorEnvironment(context, environment, environment.getParser(), environment.getParser().allocateReturnID(), true, true,
94 new UniqueMethodIdentifier());
95 final MethodTranslator methodCompiler = new MethodTranslator(context, this, newEnvironment, false, source);
96 final MethodDefinitionNode functionExprNode = methodCompiler.compileFunctionNode(translate(node.getPosition()), node.getName(), node.getArgs(), node.getBody());
97
98 final SourceSection sourceSection = translate(node.getPosition());
99 return new AddMethodNode(context, sourceSection, new SelfNode(context, sourceSection), functionExprNode);
100 }
101
102 @Override
103 public Object visitClassVarAsgnNode(org.jrubyparser.ast.ClassVarAsgnNode node) {
104 final SourceSection sourceSection = translate(node.getPosition());
105
106 final RubyNode receiver = new SelfNode(context, sourceSection);
107
108 final RubyNode rhs = (RubyNode) node.getValue().accept(this);
109
110 return new WriteClassVariableNode(context, sourceSection, node.getName(), receiver, rhs);
111 }
112
113 @Override
114 public Object visitClassVarNode(org.jrubyparser.ast.ClassVarNode node) {
115 final SourceSection sourceSection = translate(node.getPosition());
116 return new ReadClassVariableNode(context, sourceSection, node.getName(), new SelfNode(context, sourceSection));
117 }
118
119 @Override
120 public Object visitAliasNode(org.jrubyparser.ast.AliasNode node) {
121 final SourceSection sourceSection = translate(node.getPosition());
122
123 final org.jrubyparser.ast.LiteralNode oldName = (org.jrubyparser.ast.LiteralNode) node.getOldName();
124 final org.jrubyparser.ast.LiteralNode newName = (org.jrubyparser.ast.LiteralNode) node.getNewName();
125
126 return new AliasNode(context, sourceSection, new SelfNode(context, sourceSection), newName.getName(), oldName.getName());
127 }
128
129 @Override
130 protected RubyNode getModuleToDefineModulesIn(SourceSection sourceSection) {
131 return new SelfNode(context, sourceSection);
132 }
133
134 }