mirror of https://github.com/aamine/cbc
* net/loveruby/cflat/ast/LocalScope.java: new subclass of Scope.
* net/loveruby/cflat/ast/Scope.java: move local scope only methods to LocalScope class. * net/loveruby/cflat/ast/ToplevelScope.java: local scope only methods are moved to LocalScope, do not need to disable #variables, #allVariables, ... * net/loveruby/cflat/ast/Frame.java: is useless, removed. * net/loveruby/cflat/ast/DefinedFunction.java: Frame -> LocalScope. * net/loveruby/cflat/ast/BlockNode.java: Scope -> LocalScope. * net/loveruby/cflat/compiler/LocalReferenceResolver.java: Frame removed. * net/loveruby/cflat/compiler/LocalReferenceResolver.java: Scope -> LocalScope. * net/loveruby/cflat/compiler/LocalReferenceResolver.java (pushScope): check duplicated local variables. git-svn-id: file:///Users/aamine/c/gitwork/public/cbc/trunk@3888 1b9489fe-b721-0410-924e-b54b9192deb8
This commit is contained in:
parent
209116f66a
commit
6895ce1d67
27
ChangeLog
27
ChangeLog
|
|
@ -1,3 +1,30 @@
|
|||
Mon Feb 11 04:26:04 2008 Minero Aoki <aamine@loveruby.net>
|
||||
|
||||
* net/loveruby/cflat/ast/LocalScope.java: new subclass of Scope.
|
||||
|
||||
* net/loveruby/cflat/ast/Scope.java: move local scope only methods
|
||||
to LocalScope class.
|
||||
|
||||
* net/loveruby/cflat/ast/ToplevelScope.java: local scope only
|
||||
methods are moved to LocalScope, do not need to disable
|
||||
#variables, #allVariables, ...
|
||||
|
||||
* net/loveruby/cflat/ast/Frame.java: is useless, removed.
|
||||
|
||||
* net/loveruby/cflat/ast/DefinedFunction.java: Frame ->
|
||||
LocalScope.
|
||||
|
||||
* net/loveruby/cflat/ast/BlockNode.java: Scope -> LocalScope.
|
||||
|
||||
* net/loveruby/cflat/compiler/LocalReferenceResolver.java: Frame
|
||||
removed.
|
||||
|
||||
* net/loveruby/cflat/compiler/LocalReferenceResolver.java: Scope
|
||||
-> LocalScope.
|
||||
|
||||
* net/loveruby/cflat/compiler/LocalReferenceResolver.java
|
||||
(pushScope): check duplicated local variables.
|
||||
|
||||
Mon Feb 11 03:59:19 2008 Minero Aoki <aamine@loveruby.net>
|
||||
|
||||
* net/loveruby/cflat/ast/Scope.java: use LinkedHashMap to unify
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import java.util.*;
|
|||
public class BlockNode extends StmtNode {
|
||||
protected List variables;
|
||||
protected List stmts;
|
||||
protected LocalScope scope;
|
||||
|
||||
public BlockNode(Location loc, List vars, List ss) {
|
||||
super(loc);
|
||||
|
|
@ -24,14 +25,12 @@ public class BlockNode extends StmtNode {
|
|||
return (Node)stmts.get(stmts.size() - 1);
|
||||
}
|
||||
|
||||
protected Scope scope;
|
||||
|
||||
public Scope scope() {
|
||||
public LocalScope scope() {
|
||||
return scope;
|
||||
}
|
||||
|
||||
public void setScope(Scope s) {
|
||||
scope = s;
|
||||
public void setScope(LocalScope scope) {
|
||||
this.scope = scope;
|
||||
}
|
||||
|
||||
protected void _dump(Dumper d) {
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ public class DefinedFunction extends Function {
|
|||
protected Params params;
|
||||
protected BlockNode body;
|
||||
protected Map jumpMap;
|
||||
protected Frame frame;
|
||||
protected LocalScope scope;
|
||||
|
||||
public DefinedFunction(LabelPool pool, boolean priv, TypeNode type,
|
||||
String name, Params params, BlockNode body) {
|
||||
|
|
@ -30,8 +30,8 @@ public class DefinedFunction extends Function {
|
|||
return body;
|
||||
}
|
||||
|
||||
public void setFrame(Frame f) {
|
||||
frame = f;
|
||||
public void setScope(LocalScope scope) {
|
||||
this.scope = scope;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -40,7 +40,7 @@ public class DefinedFunction extends Function {
|
|||
* Does NOT include static local variables.
|
||||
*/
|
||||
public Iterator localVariables() {
|
||||
return frame.allVariables();
|
||||
return scope.allVariables();
|
||||
}
|
||||
|
||||
public boolean isDefined() {
|
||||
|
|
|
|||
|
|
@ -1,36 +0,0 @@
|
|||
package net.loveruby.cflat.ast;
|
||||
import java.util.*;
|
||||
|
||||
public class Frame extends Scope {
|
||||
public Frame(ToplevelScope up) {
|
||||
super(up);
|
||||
}
|
||||
|
||||
public List staticLocalVariables() {
|
||||
List result = new ArrayList();
|
||||
Iterator scopes = allChildren();
|
||||
while (scopes.hasNext()) {
|
||||
Scope s = (Scope)scopes.next();
|
||||
Iterator vars = s.entities.values().iterator();
|
||||
while (vars.hasNext()) {
|
||||
DefinedVariable var = (DefinedVariable)vars.next();
|
||||
if (var.isPrivate()) {
|
||||
result.add(var);
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public long numLocalVariables() {
|
||||
return bodyScope().numAllEntities();
|
||||
}
|
||||
|
||||
public Iterator localVariables() {
|
||||
return bodyScope().variables();
|
||||
}
|
||||
|
||||
private Scope bodyScope() {
|
||||
return (Scope)children.get(0);
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,85 @@
|
|||
package net.loveruby.cflat.ast;
|
||||
import net.loveruby.cflat.compiler.ErrorHandler;
|
||||
import net.loveruby.cflat.exception.*;
|
||||
import java.util.*;
|
||||
|
||||
public class LocalScope extends Scope {
|
||||
protected long numAllEntities;
|
||||
|
||||
public LocalScope(Scope up) {
|
||||
super(up);
|
||||
numAllEntities = -1;
|
||||
}
|
||||
|
||||
public boolean isToplevel() {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Returns local variables defined in this scope.
|
||||
// Does includes all nested local variables.
|
||||
// Does NOT include static local variables.
|
||||
public Iterator variables() {
|
||||
return variablesList().iterator();
|
||||
}
|
||||
|
||||
protected List variablesList() {
|
||||
List result = new ArrayList();
|
||||
Iterator ents = entities.values().iterator();
|
||||
while (ents.hasNext()) {
|
||||
Entity ent = (Entity)ents.next();
|
||||
if (ent instanceof DefinedVariable) {
|
||||
DefinedVariable var = (DefinedVariable)ent;
|
||||
if (!var.isPrivate()) {
|
||||
result.add(var);
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public long numAllEntities() {
|
||||
if (numAllEntities < 0) {
|
||||
Iterator cs = allChildren();
|
||||
long n = 0;
|
||||
while (cs.hasNext()) {
|
||||
Scope c = (Scope)cs.next();
|
||||
n += c.numEntities();
|
||||
}
|
||||
numAllEntities = n;
|
||||
}
|
||||
return numAllEntities;
|
||||
}
|
||||
|
||||
// Returns all function local variables defined in this scope.
|
||||
// Does includes all nested local variables.
|
||||
// Does NOT include static local variables.
|
||||
public Iterator allVariables() {
|
||||
return allEntities().iterator();
|
||||
}
|
||||
|
||||
protected List allEntities() {
|
||||
List result = new ArrayList();
|
||||
Iterator scopes = allChildren();
|
||||
while (scopes.hasNext()) {
|
||||
LocalScope s = (LocalScope)scopes.next();
|
||||
result.addAll(s.variablesList());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public List staticLocalVariables() {
|
||||
List result = new ArrayList();
|
||||
Iterator scopes = allChildren();
|
||||
while (scopes.hasNext()) {
|
||||
LocalScope s = (LocalScope)scopes.next();
|
||||
Iterator vars = s.entities.values().iterator();
|
||||
while (vars.hasNext()) {
|
||||
DefinedVariable var = (DefinedVariable)vars.next();
|
||||
if (var.isPrivate()) {
|
||||
result.add(var);
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
|
@ -3,7 +3,7 @@ import net.loveruby.cflat.compiler.ErrorHandler;
|
|||
import net.loveruby.cflat.exception.*;
|
||||
import java.util.*;
|
||||
|
||||
public class Scope {
|
||||
abstract public class Scope {
|
||||
protected Scope parent;
|
||||
protected List children;
|
||||
protected Map entities;
|
||||
|
|
@ -17,9 +17,7 @@ public class Scope {
|
|||
entities = new LinkedHashMap();
|
||||
}
|
||||
|
||||
public boolean isToplevel() {
|
||||
return false;
|
||||
}
|
||||
abstract public boolean isToplevel();
|
||||
|
||||
public ToplevelScope toplevel() {
|
||||
Scope s = this;
|
||||
|
|
@ -86,58 +84,6 @@ public class Scope {
|
|||
return entities.size();
|
||||
}
|
||||
|
||||
// Returns local variables defined in this scope.
|
||||
// Does includes all nested local variables.
|
||||
// Does NOT include static local variables.
|
||||
public Iterator variables() {
|
||||
return variablesList().iterator();
|
||||
}
|
||||
|
||||
protected List variablesList() {
|
||||
List result = new ArrayList();
|
||||
Iterator ents = entities.values().iterator();
|
||||
while (ents.hasNext()) {
|
||||
Entity ent = (Entity)ents.next();
|
||||
if (ent instanceof DefinedVariable) {
|
||||
DefinedVariable var = (DefinedVariable)ent;
|
||||
if (!var.isPrivate()) {
|
||||
result.add(var);
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public long numAllEntities() {
|
||||
if (numAllEntities < 0) {
|
||||
Iterator cs = allChildren();
|
||||
long n = 0;
|
||||
while (cs.hasNext()) {
|
||||
Scope c = (Scope)cs.next();
|
||||
n += c.numEntities();
|
||||
}
|
||||
numAllEntities = n;
|
||||
}
|
||||
return numAllEntities;
|
||||
}
|
||||
|
||||
// Returns all function local variables defined in this scope.
|
||||
// Does includes all nested local variables.
|
||||
// Does NOT include static local variables.
|
||||
public Iterator allVariables() {
|
||||
return allEntities().iterator();
|
||||
}
|
||||
|
||||
protected List allEntities() {
|
||||
List result = new ArrayList();
|
||||
Iterator scopes = allChildren();
|
||||
while (scopes.hasNext()) {
|
||||
Scope s = (Scope)scopes.next();
|
||||
result.addAll(s.variablesList());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public void checkReferences(ErrorHandler h) {
|
||||
Iterator ents = entities.values().iterator();
|
||||
while (ents.hasNext()) {
|
||||
|
|
|
|||
|
|
@ -25,29 +25,13 @@ public class ToplevelScope extends Scope {
|
|||
}
|
||||
// #@@}
|
||||
|
||||
public Iterator variables() {
|
||||
throw new Error("TopScope#variables called");
|
||||
}
|
||||
|
||||
public Iterator allVariables() {
|
||||
throw new Error("TopScope#allVariables called");
|
||||
}
|
||||
|
||||
public long numAllEntities() {
|
||||
throw new Error("TopScope#numAllEntities called");
|
||||
}
|
||||
|
||||
protected List allEntities() {
|
||||
throw new Error("TopScope#allEntities called");
|
||||
}
|
||||
|
||||
protected List staticLocalVariables() {
|
||||
if (staticLocalVariables == null) {
|
||||
staticLocalVariables = new ArrayList();
|
||||
Iterator frames = children.iterator();
|
||||
while (frames.hasNext()) {
|
||||
Frame f = (Frame)frames.next();
|
||||
staticLocalVariables.addAll(f.staticLocalVariables());
|
||||
Iterator scopes = children.iterator();
|
||||
while (scopes.hasNext()) {
|
||||
LocalScope s = (LocalScope)scopes.next();
|
||||
staticLocalVariables.addAll(s.staticLocalVariables());
|
||||
}
|
||||
Map seqTable = new HashMap();
|
||||
Iterator vars = staticLocalVariables.iterator();
|
||||
|
|
|
|||
|
|
@ -65,35 +65,13 @@ public class LocalReferenceResolver extends Visitor {
|
|||
protected void resolveFunctions(Iterator funcs) {
|
||||
while (funcs.hasNext()) {
|
||||
DefinedFunction func = (DefinedFunction)funcs.next();
|
||||
pushFrame(func.parameters());
|
||||
pushScope(func.parameters());
|
||||
resolve(func.body());
|
||||
func.setFrame(popFrame());
|
||||
func.setScope(popScope());
|
||||
}
|
||||
}
|
||||
// #@@}
|
||||
|
||||
// #@@range/pushFrame{
|
||||
protected void pushFrame(Iterator params) {
|
||||
Frame frame = new Frame(toplevel);
|
||||
while (params.hasNext()) {
|
||||
Parameter param = (Parameter)params.next();
|
||||
if (frame.isDefinedLocally(param.name())) {
|
||||
error(param, "duplicated parameter: " + param.name());
|
||||
}
|
||||
else {
|
||||
frame.declareEntity(param);
|
||||
}
|
||||
}
|
||||
scopeStack.addLast(frame);
|
||||
}
|
||||
// #@@}
|
||||
|
||||
// #@@range/popFrame{
|
||||
protected Frame popFrame() {
|
||||
return (Frame)scopeStack.removeLast();
|
||||
}
|
||||
// #@@}
|
||||
|
||||
// #@@range/BlockNode{
|
||||
public void visit(BlockNode node) {
|
||||
pushScope(node.variables());
|
||||
|
|
@ -104,17 +82,24 @@ public class LocalReferenceResolver extends Visitor {
|
|||
|
||||
// #@@range/pushScope{
|
||||
protected void pushScope(Iterator vars) {
|
||||
Scope scope = new Scope(currentScope());
|
||||
LocalScope scope = new LocalScope(currentScope());
|
||||
while (vars.hasNext()) {
|
||||
scope.declareEntity((DefinedVariable)vars.next());
|
||||
DefinedVariable var = (DefinedVariable)vars.next();
|
||||
if (scope.isDefinedLocally(var.name())) {
|
||||
error(var, "duplicated variable in scope: " + var.name());
|
||||
}
|
||||
else {
|
||||
scope.declareEntity(var);
|
||||
}
|
||||
scope.declareEntity(var);
|
||||
}
|
||||
scopeStack.addLast(scope);
|
||||
}
|
||||
// #@@}
|
||||
|
||||
// #@@range/popScope{
|
||||
protected Scope popScope() {
|
||||
return (Scope)scopeStack.removeLast();
|
||||
protected LocalScope popScope() {
|
||||
return (LocalScope)scopeStack.removeLast();
|
||||
}
|
||||
// #@@}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue