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>
|
Mon Feb 11 03:59:19 2008 Minero Aoki <aamine@loveruby.net>
|
||||||
|
|
||||||
* net/loveruby/cflat/ast/Scope.java: use LinkedHashMap to unify
|
* net/loveruby/cflat/ast/Scope.java: use LinkedHashMap to unify
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ import java.util.*;
|
||||||
public class BlockNode extends StmtNode {
|
public class BlockNode extends StmtNode {
|
||||||
protected List variables;
|
protected List variables;
|
||||||
protected List stmts;
|
protected List stmts;
|
||||||
|
protected LocalScope scope;
|
||||||
|
|
||||||
public BlockNode(Location loc, List vars, List ss) {
|
public BlockNode(Location loc, List vars, List ss) {
|
||||||
super(loc);
|
super(loc);
|
||||||
|
|
@ -24,14 +25,12 @@ public class BlockNode extends StmtNode {
|
||||||
return (Node)stmts.get(stmts.size() - 1);
|
return (Node)stmts.get(stmts.size() - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected Scope scope;
|
public LocalScope scope() {
|
||||||
|
|
||||||
public Scope scope() {
|
|
||||||
return scope;
|
return scope;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setScope(Scope s) {
|
public void setScope(LocalScope scope) {
|
||||||
scope = s;
|
this.scope = scope;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void _dump(Dumper d) {
|
protected void _dump(Dumper d) {
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@ public class DefinedFunction extends Function {
|
||||||
protected Params params;
|
protected Params params;
|
||||||
protected BlockNode body;
|
protected BlockNode body;
|
||||||
protected Map jumpMap;
|
protected Map jumpMap;
|
||||||
protected Frame frame;
|
protected LocalScope scope;
|
||||||
|
|
||||||
public DefinedFunction(LabelPool pool, boolean priv, TypeNode type,
|
public DefinedFunction(LabelPool pool, boolean priv, TypeNode type,
|
||||||
String name, Params params, BlockNode body) {
|
String name, Params params, BlockNode body) {
|
||||||
|
|
@ -30,8 +30,8 @@ public class DefinedFunction extends Function {
|
||||||
return body;
|
return body;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setFrame(Frame f) {
|
public void setScope(LocalScope scope) {
|
||||||
frame = f;
|
this.scope = scope;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -40,7 +40,7 @@ public class DefinedFunction extends Function {
|
||||||
* Does NOT include static local variables.
|
* Does NOT include static local variables.
|
||||||
*/
|
*/
|
||||||
public Iterator localVariables() {
|
public Iterator localVariables() {
|
||||||
return frame.allVariables();
|
return scope.allVariables();
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isDefined() {
|
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 net.loveruby.cflat.exception.*;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
public class Scope {
|
abstract public class Scope {
|
||||||
protected Scope parent;
|
protected Scope parent;
|
||||||
protected List children;
|
protected List children;
|
||||||
protected Map entities;
|
protected Map entities;
|
||||||
|
|
@ -17,9 +17,7 @@ public class Scope {
|
||||||
entities = new LinkedHashMap();
|
entities = new LinkedHashMap();
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isToplevel() {
|
abstract public boolean isToplevel();
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ToplevelScope toplevel() {
|
public ToplevelScope toplevel() {
|
||||||
Scope s = this;
|
Scope s = this;
|
||||||
|
|
@ -86,58 +84,6 @@ public class Scope {
|
||||||
return entities.size();
|
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) {
|
public void checkReferences(ErrorHandler h) {
|
||||||
Iterator ents = entities.values().iterator();
|
Iterator ents = entities.values().iterator();
|
||||||
while (ents.hasNext()) {
|
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() {
|
protected List staticLocalVariables() {
|
||||||
if (staticLocalVariables == null) {
|
if (staticLocalVariables == null) {
|
||||||
staticLocalVariables = new ArrayList();
|
staticLocalVariables = new ArrayList();
|
||||||
Iterator frames = children.iterator();
|
Iterator scopes = children.iterator();
|
||||||
while (frames.hasNext()) {
|
while (scopes.hasNext()) {
|
||||||
Frame f = (Frame)frames.next();
|
LocalScope s = (LocalScope)scopes.next();
|
||||||
staticLocalVariables.addAll(f.staticLocalVariables());
|
staticLocalVariables.addAll(s.staticLocalVariables());
|
||||||
}
|
}
|
||||||
Map seqTable = new HashMap();
|
Map seqTable = new HashMap();
|
||||||
Iterator vars = staticLocalVariables.iterator();
|
Iterator vars = staticLocalVariables.iterator();
|
||||||
|
|
|
||||||
|
|
@ -65,35 +65,13 @@ public class LocalReferenceResolver extends Visitor {
|
||||||
protected void resolveFunctions(Iterator funcs) {
|
protected void resolveFunctions(Iterator funcs) {
|
||||||
while (funcs.hasNext()) {
|
while (funcs.hasNext()) {
|
||||||
DefinedFunction func = (DefinedFunction)funcs.next();
|
DefinedFunction func = (DefinedFunction)funcs.next();
|
||||||
pushFrame(func.parameters());
|
pushScope(func.parameters());
|
||||||
resolve(func.body());
|
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{
|
// #@@range/BlockNode{
|
||||||
public void visit(BlockNode node) {
|
public void visit(BlockNode node) {
|
||||||
pushScope(node.variables());
|
pushScope(node.variables());
|
||||||
|
|
@ -104,17 +82,24 @@ public class LocalReferenceResolver extends Visitor {
|
||||||
|
|
||||||
// #@@range/pushScope{
|
// #@@range/pushScope{
|
||||||
protected void pushScope(Iterator vars) {
|
protected void pushScope(Iterator vars) {
|
||||||
Scope scope = new Scope(currentScope());
|
LocalScope scope = new LocalScope(currentScope());
|
||||||
while (vars.hasNext()) {
|
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);
|
scopeStack.addLast(scope);
|
||||||
}
|
}
|
||||||
// #@@}
|
// #@@}
|
||||||
|
|
||||||
// #@@range/popScope{
|
// #@@range/popScope{
|
||||||
protected Scope popScope() {
|
protected LocalScope popScope() {
|
||||||
return (Scope)scopeStack.removeLast();
|
return (LocalScope)scopeStack.removeLast();
|
||||||
}
|
}
|
||||||
// #@@}
|
// #@@}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue