* convert all source codes to Java 5 using generics and foreach stmt.

git-svn-id: file:///Users/aamine/c/gitwork/public/cbc/trunk@4067 1b9489fe-b721-0410-924e-b54b9192deb8
This commit is contained in:
Minero Aoki 2008-09-28 18:46:56 +00:00
parent 9003c4fd72
commit cd37fb1f02
50 changed files with 833 additions and 1043 deletions

View File

@ -1,3 +1,8 @@
Mon Sep 29 03:46:51 2008 Minero Aoki <aamine@loveruby.net>
* convert all source codes to Java 5 using generics and foreach
stmt.
Sun Sep 28 07:19:43 2008 Minero Aoki <aamine@loveruby.net>
* net/loveruby/cflat/compiler/Options.java (getOutputFileName):

View File

@ -13,7 +13,8 @@
<mkdir dir="${build.dir}" />
<mkdir dir="${build.classes.dir}" />
<javac destdir="${build.classes.dir}" srcdir="${src.dir}"
debug="true" source="1.4">
debug="true" optimize="true">
<compilerarg value="-Xlint:unchecked" />
<include name="net/**/*.java" />
</javac>
<jar jarfile="${build.jar}" basedir="${build.classes.dir}" />

View File

@ -2,5 +2,5 @@ package net.loveruby.cflat.asm;
import java.util.List;
public interface AsmOptimizer {
public List optimize(List assemblies);
public List<Assembly> optimize(List<Assembly> assemblies);
}

View File

@ -2,24 +2,22 @@ package net.loveruby.cflat.asm;
import java.util.*;
public class AsmStatistics {
protected Map registerUsage; // Map<Register, Integer>
protected Map insnUsage; // Map<String, Integer>
protected Map labelUsage; // Map<Label, Integer>
protected Map<Register, Integer> registerUsage;
protected Map<String, Integer> insnUsage;
protected Map<Label, Integer> labelUsage;
static public AsmStatistics collect(List assemblies) {
static public AsmStatistics collect(List<Assembly> assemblies) {
AsmStatistics stats = new AsmStatistics();
Iterator asms = assemblies.iterator();
while (asms.hasNext()) {
Assembly asm = (Assembly)asms.next();
for (Assembly asm : assemblies) {
asm.collectStatistics(stats);
}
return stats;
}
public AsmStatistics() {
registerUsage = new HashMap();
insnUsage = new HashMap();
labelUsage = new HashMap();
registerUsage = new HashMap<Register, Integer>();
insnUsage = new HashMap<String, Integer>();
labelUsage = new HashMap<Label, Integer>();
}
public boolean doesRegisterUsed(Register reg) {
@ -54,17 +52,17 @@ public class AsmStatistics {
incrementCount(labelUsage, label);
}
protected int fetchCount(Map m, Object key) {
Integer n = (Integer)m.get(key);
protected <K> int fetchCount(Map<K, Integer> m, K key) {
Integer n = m.get(key);
if (n == null) {
return 0;
}
else {
return n.intValue();
return n;
}
}
protected void incrementCount(Map m, Object key) {
m.put(key, new Integer(fetchCount(m, key) + 1));
protected <K> void incrementCount(Map<K, Integer> m, K key) {
m.put(key, fetchCount(m, key) + 1);
}
}

View File

@ -4,7 +4,7 @@ import net.loveruby.cflat.utils.*;
import java.util.*;
public class Assembler {
protected List assemblies; // List<Assembly>
protected List<Assembly> assemblies;
protected Type naturalType;
protected int commentIndentLevel;
@ -13,24 +13,22 @@ public class Assembler {
}
public Assembler(Type naturalType) {
this.assemblies = new ArrayList();
this.assemblies = new ArrayList<Assembly>();
this.naturalType = naturalType;
this.commentIndentLevel = 0;
}
public List assemblies() {
public List<Assembly> assemblies() {
return this.assemblies;
}
public void addAll(List assemblies) {
public void addAll(List<Assembly> assemblies) {
this.assemblies.addAll(assemblies);
}
public String toSource() {
StringBuffer buf = new StringBuffer();
Iterator asms = assemblies.iterator();
while (asms.hasNext()) {
Assembly asm = (Assembly)asms.next();
for (Assembly asm : assemblies) {
buf.append(asm.toSource());
buf.append("\n");
}

View File

@ -8,9 +8,12 @@ public class IntegerLiteral extends Literal {
}
public boolean equals(Object other) {
if (!(other instanceof IntegerLiteral)) return false;
IntegerLiteral lit = (IntegerLiteral)other;
return lit.value == this.value;
return (other instanceof IntegerLiteral)
&& equals((IntegerLiteral)other);
}
public boolean equals(IntegerLiteral other) {
return other.value == this.value;
}
public long value() {

View File

@ -3,19 +3,19 @@ import net.loveruby.cflat.utils.Cursor;
import java.util.*;
public class PeepholeOptimizer implements AsmOptimizer {
protected Map filterSet; // Map<String, List<Filter>>
protected Map<String, List<Filter>> filterSet;
public PeepholeOptimizer() {
this.filterSet = new HashMap();
this.filterSet = new HashMap<String, List<Filter>>();
}
public void add(Filter filter) {
String[] heads = filter.patternHeads();
for (int i = 0; i < heads.length; i++) {
String head = heads[i];
List list = (List)filterSet.get(head);
List<Filter> list = filterSet.get(head);
if (list == null) {
list = new ArrayList();
list = new ArrayList<Filter>();
list.add(filter);
filterSet.put(head, list);
}
@ -25,11 +25,11 @@ public class PeepholeOptimizer implements AsmOptimizer {
}
}
public List optimize(List assemblies) {
List result = new ArrayList();
Cursor cursor = new Cursor(assemblies);
public List<Assembly> optimize(List<Assembly> assemblies) {
List<Assembly> result = new ArrayList<Assembly>();
Cursor<Assembly> cursor = new Cursor<Assembly>(assemblies);
while (cursor.hasNext()) {
Assembly asm = (Assembly)cursor.next();
Assembly asm = cursor.next();
if (asm.isInstruction()) {
Filter matched = matchFilter(cursor);
if (matched != null) {
@ -42,14 +42,12 @@ public class PeepholeOptimizer implements AsmOptimizer {
return result;
}
protected Filter matchFilter(Cursor asms) {
protected Filter matchFilter(Cursor<Assembly> asms) {
Instruction insn = (Instruction)asms.current();
List filters = (List)filterSet.get(insn.mnemonic());
List<Filter> filters = filterSet.get(insn.mnemonic());
if (filters == null) return null;
if (filters.isEmpty()) return null;
Iterator it = filters.iterator();
while (it.hasNext()) {
Filter filter = (Filter)it.next();
for (Filter filter : filters) {
if (filter.match(asms)) {
return filter;
}
@ -180,8 +178,8 @@ public class PeepholeOptimizer implements AsmOptimizer {
abstract class Filter {
abstract public String[] patternHeads();
abstract public boolean match(Cursor asms);
abstract public void optimize(Cursor src, List dest);
abstract public boolean match(Cursor<Assembly> asms);
abstract public void optimize(Cursor<Assembly> src, List<Assembly> dest);
}
//
@ -202,11 +200,11 @@ public class PeepholeOptimizer implements AsmOptimizer {
return new String[] { pattern.name };
}
public boolean match(Cursor asms) {
public boolean match(Cursor<Assembly> asms) {
return pattern.match((Instruction)asms.current());
}
public void optimize(Cursor src, List dest) {
public void optimize(Cursor<Assembly> src, List<Assembly> dest) {
if (transform == null) {
; // remove instruction
}
@ -260,13 +258,13 @@ public class PeepholeOptimizer implements AsmOptimizer {
return jmpInsns();
}
public void optimize(Cursor src, List dest) {
public void optimize(Cursor<Assembly> src, List<Assembly> dest) {
; // remove jump
}
public boolean match(Cursor asms) {
public boolean match(Cursor<Assembly> asms) {
Instruction insn = (Instruction)asms.current();
return doesLabelFollows(asms.dup(), insn.jmpDestination());
return doesLabelFollows(asms.clone(), insn.jmpDestination());
}
/**
@ -281,9 +279,9 @@ public class PeepholeOptimizer implements AsmOptimizer {
* mov
* add
*/
protected boolean doesLabelFollows(Cursor asms, Label jmpDest) {
protected boolean doesLabelFollows(Cursor<Assembly> asms, Label jmpDest) {
while (asms.hasNext()) {
Assembly asm = (Assembly)asms.next();
Assembly asm = asms.next();
if (asm.isLabel()) {
Label label = (Label)asm;
if (label.equals(jmpDest)) {

View File

@ -22,8 +22,8 @@ public class AST extends Node {
return source.sourceName();
}
public Iterator sourceTokens() {
return source.token().iterator();
public CflatToken sourceTokens() {
return source.token();
}
public void setTypeTable(TypeTable table) {
@ -37,61 +37,64 @@ public class AST extends Node {
return this.typeTable;
}
public Iterator types() {
List result = new ArrayList();
public List<TypeDefinition> types() {
List<TypeDefinition> result = new ArrayList<TypeDefinition>();
result.addAll(declarations.defstructs());
result.addAll(declarations.defunions());
result.addAll(declarations.typedefs());
return result.iterator();
return result;
}
public Iterator declarations() {
List result = new ArrayList();
public List<Entity> declarations() {
List<Entity> result = new ArrayList<Entity>();
result.addAll(declarations.funcdecls());
result.addAll(declarations.vardecls());
return result.iterator();
return result;
}
public Iterator entities() {
List result = new ArrayList();
public List<Entity> entities() {
List<Entity> result = new ArrayList<Entity>();
result.addAll(declarations.defvars());
result.addAll(declarations.defuns());
return result.iterator();
return result;
}
public Iterator variables() {
return declarations.defvars().iterator();
public List<DefinedVariable> definedVariables() {
return declarations.defvars();
}
public boolean functionDefined() {
return !declarations.defuns().isEmpty();
}
public Iterator functions() {
return declarations.defuns().iterator();
public List<DefinedFunction> definedFunctions() {
return declarations.defuns();
}
public Iterator allFunctions() {
List result = new ArrayList();
public List<Function> allFunctions() {
List<Function> result = new ArrayList<Function>();
result.addAll(declarations.defuns());
result.addAll(declarations.funcdecls());
return result.iterator();
return result;
}
public ToplevelScope scope() {
return scope;
}
public Iterator allGlobalVariables() {
return scope.allGlobalVariables().iterator();
/** a list of all defined/declared global-scope variables */
public List<Variable> allGlobalVariables() {
return scope.allGlobalVariables();
}
public Iterator globalVariables() {
return scope.globalVariables().iterator();
/** a list of defined initialized global variables */
public List<DefinedVariable> definedGlobalVariables() {
return scope.definedGlobalVariables();
}
public Iterator commonSymbols() {
return scope.commonSymbols().iterator();
/** a list of defined uninitialized global variables */
public List<DefinedVariable> definedCommonSymbols() {
return scope.definedCommonSymbols();
}
public ConstantTable constantTable() {
@ -103,8 +106,8 @@ public class AST extends Node {
}
protected void _dump(Dumper d) {
d.printNodeList("variables", variables());
d.printNodeList("functions", functions());
d.printNodeList("variables", definedVariables());
d.printNodeList("functions", definedFunctions());
}
public void accept(ASTVisitor visitor) {

View File

@ -2,27 +2,27 @@ package net.loveruby.cflat.ast;
import java.util.*;
public class BlockNode extends StmtNode {
protected List variables;
protected List stmts;
protected List<DefinedVariable> variables;
protected List<Node> stmts;
protected LocalScope scope;
public BlockNode(Location loc, List vars, List ss) {
public BlockNode(Location loc, List<DefinedVariable> vars, List<Node> stmts) {
super(loc);
variables = vars;
stmts = ss;
this.variables = vars;
this.stmts = stmts;
}
public Iterator variables() {
return variables.iterator();
public List<DefinedVariable> variables() {
return variables;
}
public Iterator stmts() {
return stmts.iterator();
public List<Node> stmts() {
return stmts;
}
public Node tailStmt() {
if (stmts.isEmpty()) return null;
return (Node)stmts.get(stmts.size() - 1);
return stmts.get(stmts.size() - 1);
}
public LocalScope scope() {

View File

@ -5,10 +5,11 @@ import java.util.*;
public class CaseNode extends StmtNode {
protected LabelPool pool;
protected Label beginLabel;
protected List values; // List<Node>
protected List<ExprNode> values;
protected BlockNode body;
public CaseNode(Location loc, LabelPool pool, List values, BlockNode body) {
public CaseNode(Location loc, LabelPool pool,
List<ExprNode> values, BlockNode body) {
super(loc);
this.pool = pool;
this.values = values;
@ -16,8 +17,8 @@ public class CaseNode extends StmtNode {
this.beginLabel = null;
}
public Iterator values() {
return values.iterator();
public List<ExprNode> values() {
return values;
}
public boolean isDefault() {

View File

@ -7,7 +7,7 @@ import java.util.*;
/**
* Token wrapper.
*/
public class CflatToken {
public class CflatToken implements Iterable<CflatToken> {
protected Token token;
protected boolean isSpecial;
@ -52,28 +52,28 @@ public class CflatToken {
return TextUtils.dumpString(token.image);
}
public Iterator iterator() {
return buildTokenList(new ArrayList(), token, false).iterator();
public Iterator<CflatToken> iterator() {
return buildTokenList(token, false).iterator();
}
protected Iterator tokensWithoutFirstSpecials() {
return buildTokenList(new ArrayList(), token, true).iterator();
protected List<CflatToken> tokensWithoutFirstSpecials() {
return buildTokenList(token, true);
}
protected List buildTokenList(List tokens, Token first,
boolean rejectFirstSpecials) {
protected List<CflatToken> buildTokenList(Token first, boolean rejectFirstSpecials) {
List<CflatToken> result = new ArrayList<CflatToken>();
boolean rejectSpecials = rejectFirstSpecials;
for (Token t = first; t != null; t = t.next) {
if (t.specialToken != null && !rejectSpecials) {
Token s = specialTokenHead(t.specialToken);
for (; s != null; s = s.next) {
tokens.add(new CflatToken(s));
result.add(new CflatToken(s));
}
}
tokens.add(new CflatToken(t));
result.add(new CflatToken(t));
rejectSpecials = false;
}
return tokens;
return result;
}
protected Token specialTokenHead(Token firstSpecial) {
@ -86,9 +86,7 @@ public class CflatToken {
public String includedLine() {
StringBuffer buf = new StringBuffer();
Iterator toks = tokensWithoutFirstSpecials();
while (toks.hasNext()) {
CflatToken t = (CflatToken)toks.next();
for (CflatToken t : tokensWithoutFirstSpecials()) {
int idx = t.image().indexOf("\n");
if (idx >= 0) {
buf.append(t.image().substring(0, idx));

View File

@ -3,10 +3,10 @@ import net.loveruby.cflat.type.*;
import java.util.*;
abstract public class CompositeTypeDefinition extends TypeDefinition {
protected List members; // List<Slot>
protected List<Slot> members;
public CompositeTypeDefinition(Location loc,
TypeRef ref, String name, List membs) {
public CompositeTypeDefinition(Location loc, TypeRef ref,
String name, List<Slot> membs) {
super(loc, ref, name);
members = membs;
}
@ -17,7 +17,7 @@ abstract public class CompositeTypeDefinition extends TypeDefinition {
abstract public String kind();
public List members() {
public List<Slot> members() {
return members;
}

View File

@ -1,12 +1,12 @@
package net.loveruby.cflat.ast;
import java.util.*;
public class ConstantTable {
protected Map table;
public class ConstantTable implements Iterable<ConstantEntry> {
protected Map<String, ConstantEntry> table;
protected long id;
public ConstantTable() {
table = new LinkedHashMap();
table = new LinkedHashMap<String, ConstantEntry>();
id = 0;
}
@ -15,7 +15,7 @@ public class ConstantTable {
}
public ConstantEntry intern(String s) {
ConstantEntry ent = (ConstantEntry)table.get(s);
ConstantEntry ent = table.get(s);
if (ent == null) {
ent = new ConstantEntry(id++, s);
table.put(s, ent);
@ -23,7 +23,11 @@ public class ConstantTable {
return ent;
}
public Iterator entries() {
public Collection<ConstantEntry> entries() {
return table.values();
}
public Iterator<ConstantEntry> iterator() {
return table.values().iterator();
}
}

View File

@ -2,91 +2,89 @@ package net.loveruby.cflat.ast;
import java.util.*;
public class Declarations {
protected Set defvars, vardecls, defuns, funcdecls;
protected Set defstructs, defunions, typedefs;
protected Set<DefinedVariable> defvars;
protected Set<UndefinedVariable> vardecls;
protected Set<DefinedFunction> defuns;
protected Set<UndefinedFunction> funcdecls;
protected Set<StructNode> defstructs;
protected Set<UnionNode> defunions;
protected Set<TypedefNode> typedefs;
public Declarations() {
defvars = new LinkedHashSet();
vardecls = new LinkedHashSet();
defuns = new LinkedHashSet();
funcdecls = new LinkedHashSet();
defstructs = new LinkedHashSet();
defunions = new LinkedHashSet();
typedefs = new LinkedHashSet();
defvars = new LinkedHashSet<DefinedVariable>();
vardecls = new LinkedHashSet<UndefinedVariable>();
defuns = new LinkedHashSet<DefinedFunction>();
funcdecls = new LinkedHashSet<UndefinedFunction>();
defstructs = new LinkedHashSet<StructNode>();
defunions = new LinkedHashSet<UnionNode>();
typedefs = new LinkedHashSet<TypedefNode>();
}
public void add(Declarations decls) {
updateSet(vardecls, decls.vardecls());
updateSet(funcdecls, decls.funcdecls());
updateSet(defstructs, decls.defstructs());
updateSet(defunions, decls.defunions());
updateSet(typedefs, decls.typedefs());
}
protected void updateSet(Set s, List items) {
Iterator i = items.iterator();
while (i.hasNext()) {
s.add(i.next());
}
vardecls.addAll(decls.vardecls());
funcdecls.addAll(decls.funcdecls());
defstructs.addAll(decls.defstructs());
defunions.addAll(decls.defunions());
typedefs.addAll(decls.typedefs());
}
public void addDefvar(DefinedVariable var) {
defvars.add(var);
}
public void addDefvars(List vars) {
updateSet(defvars, vars);
public void addDefvars(List<DefinedVariable> vars) {
defvars.addAll(vars);
}
public List defvars() {
return new ArrayList(defvars);
public List<DefinedVariable> defvars() {
return new ArrayList<DefinedVariable>(defvars);
}
public void addVardecl(UndefinedVariable var) {
vardecls.add(var);
}
public List vardecls() {
return new ArrayList(vardecls);
public List<UndefinedVariable> vardecls() {
return new ArrayList<UndefinedVariable>(vardecls);
}
public void addDefun(Function func) {
public void addDefun(DefinedFunction func) {
defuns.add(func);
}
public List defuns() {
return new ArrayList(defuns);
public List<DefinedFunction> defuns() {
return new ArrayList<DefinedFunction>(defuns);
}
public void addFuncdecl(UndefinedFunction func) {
funcdecls.add(func);
}
public List funcdecls() {
return new ArrayList(funcdecls);
public List<UndefinedFunction> funcdecls() {
return new ArrayList<UndefinedFunction>(funcdecls);
}
public void addDefstruct(StructNode n) {
defstructs.add(n);
}
public List defstructs() {
return new ArrayList(defstructs);
public List<StructNode> defstructs() {
return new ArrayList<StructNode>(defstructs);
}
public void addDefunion(UnionNode n) {
defunions.add(n);
}
public List defunions() {
return new ArrayList(defunions);
public List<UnionNode> defunions() {
return new ArrayList<UnionNode>(defunions);
}
public void addTypedef(TypedefNode n) {
typedefs.add(n);
}
public List typedefs() {
return new ArrayList(typedefs);
public List<TypedefNode> typedefs() {
return new ArrayList<TypedefNode>(typedefs);
}
}

View File

@ -9,24 +9,27 @@ public class DefinedFunction extends Function {
protected LabelPool labelPool;
protected Params params;
protected BlockNode body;
protected Map jumpMap;
protected Map<String, JumpEntry> jumpMap;
protected LocalScope scope;
public DefinedFunction(LabelPool pool, boolean priv, TypeNode type,
String name, Params params, BlockNode body) {
public DefinedFunction(LabelPool pool,
boolean priv,
TypeNode type,
String name,
Params params,
BlockNode body) {
super(priv, type, name);
this.labelPool = pool;
this.params = params;
this.body = body;
this.jumpMap = new HashMap();
this.jumpMap = new HashMap<String, JumpEntry>();
}
public boolean isDefined() {
return true;
}
/** Returns an iterator to the list of parameter slots (Slot). */
public Iterator parameters() {
public List<Parameter> parameters() {
return params.parameters();
}
@ -43,7 +46,7 @@ public class DefinedFunction extends Function {
* Does NOT include paramters.
* Does NOT include static local variables.
*/
public Iterator localVariables() {
public List<DefinedVariable> localVariables() {
return scope.allLocalVariables();
}
@ -79,7 +82,7 @@ public class DefinedFunction extends Function {
}
protected JumpEntry getJumpEntry(String name) {
JumpEntry ent = (JumpEntry)jumpMap.get(name);
JumpEntry ent = jumpMap.get(name);
if (ent == null) {
ent = new JumpEntry(labelPool.newLabel());
jumpMap.put(name, ent);
@ -88,11 +91,9 @@ public class DefinedFunction extends Function {
}
public void checkJumpLinks(ErrorHandler handler) {
Iterator ents = jumpMap.entrySet().iterator();
while (ents.hasNext()) {
Map.Entry ent = (Map.Entry)ents.next();
String labelName = (String)ent.getKey();
JumpEntry jump = (JumpEntry)ent.getValue();
for (Map.Entry<String, JumpEntry> ent : jumpMap.entrySet()) {
String labelName = ent.getKey();
JumpEntry jump = ent.getValue();
if (!jump.isDefined) {
handler.error(jump.location,
name + ": undefined label: " + labelName);

View File

@ -15,24 +15,14 @@ public class Dumper {
public void printClass(Object obj, Location loc) {
printIndent();
stream.println("<<" + className(obj) + ">> (" + loc + ")");
stream.println("<<" + obj.getClass().getSimpleName() + ">> (" + loc + ")");
}
protected String className(Object obj) {
String[] ids = obj.getClass().getName().split("\\.");
return ids[ids.length - 1];
}
public void printNodeList(String name, List list) {
printNodeList(name, list.iterator());
}
public void printNodeList(String name, Iterator list) {
public void printNodeList(String name, List<? extends Node> nodes) {
printIndent();
stream.println(name + ":");
indent();
while (list.hasNext()) {
Node n = (Node)list.next();
for (Node n : nodes) {
n.dump(this);
}
unindent();

View File

@ -1,97 +0,0 @@
package net.loveruby.cflat.ast;
import net.loveruby.cflat.type.*;
import java.util.*;
public class FixedParams extends Params {
protected Location location;
protected List parameters;
public FixedParams(List params) {
this(null, params);
}
public FixedParams(Location loc, List params) {
super();
this.location = loc;
this.parameters = params;
}
public Location location() {
return location;
}
/**
* For DefinedFunction and UndefinedFunction, returns an iterator to
* the list of parameters (Parameter). For FunctionType, returns an
* iterator to the list of parameter type (Type).
*/
public Iterator parameters() {
return parameters.iterator();
}
public int argc() {
return parameters.size();
}
public int minArgc() {
return parameters.size();
}
/**
* For DefinedFunction and UndefinedFunction, returns a list of
* parameters (Parameter). For FunctionType, returns a list of
* parameter types (Type).
*/
protected List parametersList() {
return parameters;
}
public boolean isVararg() {
return false;
}
public boolean equals(Object other) {
if (!(other instanceof FixedParams)) return false;
FixedParams params = (FixedParams)other;
return parameters.equals(params.parametersList());
}
public Params internTypes(TypeTable table) {
Iterator it = parameters.iterator();
List types = new ArrayList();
while (it.hasNext()) {
types.add(table.get((TypeRef)it.next()));
}
return new FixedParams(location, types);
}
public Params typeRefs() {
Iterator it = parameters.iterator();
List typerefs = new ArrayList();
while (it.hasNext()) {
Parameter param = (Parameter)it.next();
typerefs.add(param.typeNode().typeRef());
}
return new FixedParams(location, typerefs);
}
/** parameters is a list of Type when
* this object is hold in FunctionType. */
public Iterator types() {
return parameters.iterator();
}
public boolean isSameType(Params other) {
if (other.isVararg()) return false;
if (other.argc() != argc()) return false;
Iterator types = types();
Iterator otherTypes = other.types();
while (types.hasNext()) {
Type t = (Type)types.next();
Type tt = (Type)otherTypes.next();
if (t.isSameType(t))
return false;
}
return true;
}
}

View File

@ -5,9 +5,9 @@ import java.util.*;
public class FuncallNode extends ExprNode {
protected ExprNode expr;
protected List arguments;
protected List<ExprNode> arguments;
public FuncallNode(ExprNode expr, List arguments) {
public FuncallNode(ExprNode expr, List<ExprNode> arguments) {
this.expr = expr;
this.arguments = arguments;
}
@ -55,16 +55,16 @@ public class FuncallNode extends ExprNode {
return arguments.size();
}
public Iterator arguments() {
return arguments.iterator();
public List<ExprNode> arguments() {
return arguments;
}
// called from TypeChecker
public void replaceArgs(List args) {
public void replaceArgs(List<ExprNode> args) {
this.arguments = args;
}
public ListIterator finalArg() {
public ListIterator<ExprNode> finalArg() {
return arguments.listIterator(arguments.size());
}

View File

@ -14,7 +14,7 @@ abstract public class Function extends Entity {
public boolean isFunction() { return true; }
public boolean isInitialized() { return true; }
abstract public boolean isDefined();
abstract public Iterator parameters();
abstract public List<Parameter> parameters();
public FunctionType functionType() {
return type().getPointerType().baseType().getFunctionType();

View File

@ -4,83 +4,82 @@ import net.loveruby.cflat.exception.*;
import java.util.*;
public class LocalScope extends Scope {
protected long numAllEntities;
protected Scope parent;
protected Map<String, DefinedVariable> variables;
public LocalScope(Scope up) {
super(up);
numAllEntities = -1;
public LocalScope(Scope parent) {
super();
this.parent = parent;
parent.addChild(this);
variables = new LinkedHashMap<String, DefinedVariable>();
}
public boolean isToplevel() {
return false;
}
public Iterator children() {
return children.iterator();
public ToplevelScope toplevel() {
return parent.toplevel();
}
/**
* Returns local variables defined in this scope.
* Does NOT includes children's local variables.
* Does NOT include static local variables.
*/
public Iterator variables() {
return lvarList().iterator();
public Scope parent() {
return this.parent;
}
/**
* Returns local variables defined in this scope.
* Does NOT includes children's local variables.
* Does NOT include static local variables.
*/
protected List lvarList() {
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 List<LocalScope> children() {
return children;
}
/**
* Returns the number of all entities in this scope.
* Result includes the number of children's entities.
*/
public long numAllEntities() {
if (numAllEntities < 0) {
Iterator cs = allScopes().iterator();
long n = 0;
while (cs.hasNext()) {
Scope c = (Scope)cs.next();
n += c.numEntities();
public boolean isDefinedLocally(String name) {
return variables.containsKey(name);
}
numAllEntities = n;
/** Define variable in this scope. */
// #@@range/defineVariable{
public void defineVariable(DefinedVariable var) {
if (variables.containsKey(var.name())) {
throw new Error("duplicated variable: " + var.name());
}
return numAllEntities;
variables.put(var.name(), var);
}
// #@@}
// #@@range/get{
public Entity get(String name) throws SemanticException {
DefinedVariable var = variables.get(name);
if (var != null) {
return var;
}
else {
return parent.get(name);
}
}
// #@@}
/**
* Returns all local variables in this scope.
* The result DOES includes all nested local variables,
* while it does NOT include static local variables.
*/
public Iterator allLocalVariables() {
return allLocalVariablesList().iterator();
public List<DefinedVariable> allLocalVariables() {
List<DefinedVariable> result = new ArrayList<DefinedVariable>();
for (LocalScope s : allLocalScopes()) {
result.addAll(s.localVariables());
}
return result;
}
// List<DefinedVariable>
protected List allLocalVariablesList() {
List result = new ArrayList();
Iterator scopes = allScopes().iterator();
while (scopes.hasNext()) {
LocalScope s = (LocalScope)scopes.next();
result.addAll(s.lvarList());
/**
* Returns local variables defined in this scope.
* Does NOT includes children's local variables.
* Does NOT include static local variables.
*/
public List<DefinedVariable> localVariables() {
List<DefinedVariable> result = new ArrayList<DefinedVariable>();
for (DefinedVariable var : variables.values()) {
if (!var.isPrivate()) {
result.add(var);
}
}
return result;
}
@ -88,14 +87,10 @@ public class LocalScope extends Scope {
/**
* Returns all static local variables defined in this scope.
*/
public List staticLocalVariables() {
List result = new ArrayList();
Iterator scopes = allScopes().iterator();
while (scopes.hasNext()) {
LocalScope s = (LocalScope)scopes.next();
Iterator vars = s.entities.values().iterator();
while (vars.hasNext()) {
DefinedVariable var = (DefinedVariable)vars.next();
public List<DefinedVariable> staticLocalVariables() {
List<DefinedVariable> result = new ArrayList<DefinedVariable>();
for (LocalScope s : allLocalScopes()) {
for (DefinedVariable var : s.variables.values()) {
if (var.isPrivate()) {
result.add(var);
}
@ -103,4 +98,29 @@ public class LocalScope extends Scope {
}
return result;
}
// Returns a list of all child scopes including this scope.
protected List<LocalScope> allLocalScopes() {
List<LocalScope> result = new ArrayList<LocalScope>();
collectScope(result);
return result;
}
protected void collectScope(List<LocalScope> buf) {
buf.add(this);
for (LocalScope s : children) {
s.collectScope(buf);
}
}
public void checkReferences(ErrorHandler h) {
for (DefinedVariable var : variables.values()) {
if (!var.isRefered()) {
h.warn(var.location(), "unused variable: " + var.name());
}
}
for (LocalScope c : children) {
c.checkReferences(h);
}
}
}

View File

@ -0,0 +1,55 @@
package net.loveruby.cflat.ast;
import net.loveruby.cflat.type.*;
import java.util.*;
abstract public class ParamSlots<T> extends Node {
protected Location location;
protected List<T> paramDescriptors;
protected boolean vararg;
public ParamSlots(List<T> paramDescs) {
this(null, paramDescs);
}
public ParamSlots(Location loc, List<T> paramDescs) {
this(loc, paramDescs, false);
}
protected ParamSlots(Location loc, List<T> paramDescs, boolean vararg) {
super();
this.location = loc;
this.paramDescriptors = paramDescs;
this.vararg = vararg;
}
public int argc() {
if (vararg) {
throw new Error("must not happen: Param#argc for vararg");
}
return paramDescriptors.size();
}
public int minArgc() {
return paramDescriptors.size();
}
public void acceptVarargs() {
this.vararg = true;
}
public boolean isVararg() {
return vararg;
}
public Location location() {
return location;
}
protected void _dump(Dumper d) {
throw new Error("must not happen: ParamSlots#_dump");
}
public void accept(ASTVisitor visitor) {
throw new Error("must not happen: ParamSlots#accept");
}
}

View File

@ -1,27 +1,35 @@
package net.loveruby.cflat.ast;
import net.loveruby.cflat.type.*;
import net.loveruby.cflat.type.TypeRef;
import net.loveruby.cflat.type.ParamTypeRefs;
import java.util.*;
abstract public class Params extends Node {
public Params() {
super();
public class Params extends ParamSlots<Parameter> {
public Params(Location loc, List<Parameter> paramDescs) {
super(loc, paramDescs, false);
}
abstract public Iterator parameters();
abstract public boolean isVararg();
abstract public int argc();
abstract public int minArgc();
abstract public boolean equals(Object other);
abstract public Params internTypes(TypeTable table);
abstract public Params typeRefs();
abstract public Iterator types();
abstract public boolean isSameType(Params other);
public List<Parameter> parameters() {
return paramDescriptors;
}
public ParamTypeRefs parametersTypeRef() {
List<TypeRef> typerefs = new ArrayList<TypeRef>();
for (Parameter param : paramDescriptors) {
typerefs.add(param.typeNode().typeRef());
}
return new ParamTypeRefs(location, typerefs, vararg);
}
public boolean equals(Object other) {
return (other instanceof Params) && equals((Params)other);
}
public boolean equals(Params other) {
return other.vararg == vararg
&& other.paramDescriptors.equals(paramDescriptors);
}
protected void _dump(Dumper d) {
d.printNodeList("parameters", parameters());
}
public void accept(ASTVisitor visitor) {
throw new Error("do not use Params#accept");
}
}

View File

@ -4,97 +4,19 @@ import net.loveruby.cflat.exception.*;
import java.util.*;
abstract public class Scope {
protected Scope parent;
protected List children;
protected Map entities;
protected long numAllEntities;
protected List<LocalScope> children;
public Scope(Scope up) {
parent = up;
if (up != null) up.addChild(this);
children = new ArrayList();
numAllEntities = -1;
entities = new LinkedHashMap();
public Scope() {
children = new ArrayList<LocalScope>();
}
abstract public boolean isToplevel();
abstract public ToplevelScope toplevel();
abstract public Scope parent();
public ToplevelScope toplevel() {
Scope s = this;
while (!s.isToplevel()) {
s = s.parent;
}
return (ToplevelScope)s;
}
// Returns parent scope.
// If this scope is a TopScope, parent() returns null.
public Scope parent() {
return parent;
}
protected void addChild(Scope s) {
protected void addChild(LocalScope s) {
children.add(s);
}
// Returns a list of all child scopes including this scope.
protected List allScopes() {
List result = new ArrayList();
collectScope(result);
return result;
}
protected void collectScope(List buf) {
buf.add(this);
Iterator cs = children.iterator();
while (cs.hasNext()) {
Scope c = (Scope)cs.next();
c.collectScope(buf);
}
}
/** Declare variable or function in this scope. */
// #@@range/declareEntity{
public void declareEntity(Entity ent) {
if (entities.containsKey(ent.name())) {
throw new Error("duplicated entity: " + ent.name());
}
entities.put(ent.name(), ent);
}
// #@@}
public boolean isDefinedLocally(String name) {
return entities.containsKey(name);
}
// #@@range/get{
public Entity get(String name) throws SemanticException {
Entity ent = (Entity)entities.get(name);
if (ent != null) {
return ent;
}
else {
return parent.get(name);
}
}
// #@@}
public long numEntities() {
return entities.size();
}
public void checkReferences(ErrorHandler h) {
Iterator ents = entities.values().iterator();
while (ents.hasNext()) {
Entity ent = (Entity)ents.next();
if (ent.isDefined() && ent.isPrivate() && !ent.isRefered()) {
h.warn(ent.location(), "unused variable: " + ent.name());
}
}
Iterator scopes = children.iterator();
while (scopes.hasNext()) {
Scope s = (Scope)scopes.next();
s.checkReferences(h);
}
}
abstract public Entity get(String name) throws SemanticException;
}

View File

@ -3,7 +3,7 @@ import net.loveruby.cflat.type.*;
import java.util.*;
public class StructNode extends CompositeTypeDefinition {
public StructNode(Location loc, TypeRef ref, String name, List membs) {
public StructNode(Location loc, TypeRef ref, String name, List<Slot> membs) {
super(loc, ref, name, membs);
}

View File

@ -5,11 +5,11 @@ import java.util.*;
public class SwitchNode extends StmtNode implements BreakableStmt {
protected LabelPool pool;
protected ExprNode cond;
protected List cases;
protected List<CaseNode> cases;
protected Label endLabel;
public SwitchNode(Location loc, LabelPool pool,
ExprNode cond, List cases) {
ExprNode cond, List<CaseNode> cases) {
super(loc);
this.pool = pool;
this.cond = cond;
@ -20,8 +20,8 @@ public class SwitchNode extends StmtNode implements BreakableStmt {
return cond;
}
public Iterator cases() {
return cases.iterator();
public List<CaseNode> cases() {
return cases;
}
public Label endLabel() {

View File

@ -1,23 +1,45 @@
package net.loveruby.cflat.ast;
import net.loveruby.cflat.compiler.ErrorHandler;
import net.loveruby.cflat.type.*;
import net.loveruby.cflat.exception.*;
import java.util.*;
public class ToplevelScope extends Scope {
protected List staticLocalVariables;
protected Map<String, Entity> entities;
protected List<DefinedVariable> staticLocalVariables; // cache
public ToplevelScope() {
super(null);
super();
entities = new LinkedHashMap<String, Entity>();
staticLocalVariables = null;
}
public boolean isToplevel() {
return true;
}
public ToplevelScope toplevel() {
return this;
}
public Scope parent() {
return null;
}
/** Declare variable or function in this scope. */
// #@@range/declareEntity{
public void declareEntity(Entity ent) {
if (entities.containsKey(ent.name())) {
throw new Error("duplicated entity: " + ent.name());
}
entities.put(ent.name(), ent);
}
// #@@}
/** Searches and gets entity searching scopes upto ToplevelScope. */
// #@@range/get{
public Entity get(String name) throws SemanticException {
Entity ent = (Entity)entities.get(name);
Entity ent = entities.get(name);
if (ent == null) {
throw new SemanticException("unresolved reference: " + name);
}
@ -25,32 +47,6 @@ public class ToplevelScope extends Scope {
}
// #@@}
protected List staticLocalVariables() {
if (staticLocalVariables == null) {
staticLocalVariables = new ArrayList();
Iterator scopes = children.iterator();
while (scopes.hasNext()) {
LocalScope s = (LocalScope)scopes.next();
staticLocalVariables.addAll(s.staticLocalVariables());
}
Map seqTable = new HashMap();
Iterator vars = staticLocalVariables.iterator();
while (vars.hasNext()) {
DefinedVariable var = (DefinedVariable)vars.next();
Long seq = (Long)seqTable.get(var.name());
if (seq == null) {
var.setSequence(0);
seqTable.put(var.name(), new Long(1));
}
else {
var.setSequence(seq.longValue());
seqTable.put(var.name(), new Long(seq.longValue() + 1));
}
}
}
return staticLocalVariables;
}
/** Returns a list of all global variables.
* "All global variable" means:
*
@ -58,60 +54,87 @@ public class ToplevelScope extends Scope {
* * defined or undefined
* * public or private
*/
public List allGlobalVariables() {
List result = new ArrayList();
List src = new ArrayList();
src.addAll(entities.values());
src.addAll(staticLocalVariables());
Iterator ents = src.iterator();
while (ents.hasNext()) {
Object ent = ents.next();
public List<Variable> allGlobalVariables() {
List<Variable> result = new ArrayList<Variable>();
for (Entity ent : entities.values()) {
if (ent instanceof Variable) {
result.add(ent);
result.add((Variable)ent);
}
}
result.addAll(staticLocalVariables());
return result;
}
/** Returns the list of global variables.
* A global variable is a variable which has
* global scope and is initialized. */
public List globalVariables() {
List result = new ArrayList();
List src = new ArrayList();
src.addAll(entities.values());
src.addAll(staticLocalVariables());
Iterator ents = src.iterator();
while (ents.hasNext()) {
Object ent = ents.next();
if (ent instanceof DefinedVariable) {
DefinedVariable var = (DefinedVariable)ent;
public List<DefinedVariable> definedGlobalVariables() {
List<DefinedVariable> result = new ArrayList<DefinedVariable>();
for (DefinedVariable var : definedGlobalScopeVariables()) {
if (var.hasInitializer()) {
result.add(var);
}
}
}
return result;
}
/** Returns the list of common symbols.
* A common symbol is a variable which has
* global scope and is not initialized. */
public List commonSymbols() {
List result = new ArrayList();
List src = new ArrayList();
src.addAll(entities.values());
src.addAll(staticLocalVariables());
Iterator ents = src.iterator();
while (ents.hasNext()) {
Object ent = ents.next();
if (ent instanceof DefinedVariable) {
DefinedVariable var = (DefinedVariable)ent;
public List<DefinedVariable> definedCommonSymbols() {
List<DefinedVariable> result = new ArrayList<DefinedVariable>();
for (DefinedVariable var : definedGlobalScopeVariables()) {
if (!var.hasInitializer()) {
result.add(var);
}
}
}
return result;
}
protected List<DefinedVariable> definedGlobalScopeVariables() {
List<DefinedVariable> result = new ArrayList<DefinedVariable>();
for (Entity ent : entities.values()) {
if (ent instanceof DefinedVariable) {
result.add((DefinedVariable)ent);
}
}
result.addAll(staticLocalVariables());
return result;
}
protected List<DefinedVariable> staticLocalVariables() {
if (staticLocalVariables == null) {
staticLocalVariables = new ArrayList<DefinedVariable>();
for (LocalScope s : children) {
staticLocalVariables.addAll(s.staticLocalVariables());
}
Map<String, Integer> seqTable = new HashMap<String, Integer>();
for (DefinedVariable var : staticLocalVariables) {
Integer seq = seqTable.get(var.name());
if (seq == null) {
var.setSequence(0);
seqTable.put(var.name(), 1);
}
else {
var.setSequence(seq);
seqTable.put(var.name(), seq + 1);
}
}
}
return staticLocalVariables;
}
public void checkReferences(ErrorHandler h) {
for (Entity ent : entities.values()) {
if (ent.isDefined() && ent.isPrivate() && !ent.isRefered()) {
h.warn(ent.location(), "unused variable: " + ent.name());
}
}
// do not check parameters
for (LocalScope funcScope : children) {
for (LocalScope s : funcScope.children) {
s.checkReferences(h);
}
}
}
}

View File

@ -6,12 +6,12 @@ import java.util.*;
public class UndefinedFunction extends Function {
protected Params params;
public UndefinedFunction(TypeNode t, String name, Params ps) {
public UndefinedFunction(TypeNode t, String name, Params params) {
super(false, t, name);
params = ps;
this.params = params;
}
public Iterator parameters() {
public List<Parameter> parameters() {
return params.parameters();
}

View File

@ -3,7 +3,7 @@ import net.loveruby.cflat.type.*;
import java.util.*;
public class UnionNode extends CompositeTypeDefinition {
public UnionNode(Location loc, TypeRef ref, String name, List membs) {
public UnionNode(Location loc, TypeRef ref, String name, List<Slot> membs) {
super(loc, ref, name, membs);
}

View File

@ -1,60 +0,0 @@
package net.loveruby.cflat.ast;
import net.loveruby.cflat.type.*;
import java.util.*;
public class VarParams extends Params {
protected FixedParams params;
public VarParams(FixedParams params) {
super();
this.params = params;
}
public Iterator parameters() {
return params.parameters();
}
public int argc() {
throw new Error("VarParams#argc");
}
public int minArgc() {
return params.minArgc();
}
public boolean isVararg() {
return true;
}
protected FixedParams fixedParams() {
return params;
}
public boolean equals(Object other) {
if (!(other instanceof VarParams)) return false;
VarParams params = (VarParams)other;
return params.equals(params.fixedParams());
}
public Params internTypes(TypeTable table) {
return new VarParams((FixedParams)params.internTypes(table));
}
public Params typeRefs() {
return new VarParams((FixedParams)params.typeRefs());
}
public Iterator types() {
return params.types();
}
public boolean isSameType(Params other) {
if (!other.isVararg()) return false;
VarParams otherParams = (VarParams)other;
return this.fixedParams().isSameType(otherParams.fixedParams());
}
public Location location() {
return params.location();
}
}

View File

@ -9,7 +9,7 @@ public class CodeGenerator
// #@@range/ctor{
protected CodeGeneratorOptions options;
protected ErrorHandler errorHandler;
protected LinkedList asStack;
protected LinkedList<Assembler> asStack;
protected Assembler as;
protected TypeTable typeTable;
protected DefinedFunction currentFunction;
@ -18,7 +18,7 @@ public class CodeGenerator
ErrorHandler errorHandler) {
this.options = options;
this.errorHandler = errorHandler;
this.asStack = new LinkedList();
this.asStack = new LinkedList<Assembler>();
}
// #@@}
@ -27,22 +27,28 @@ public class CodeGenerator
public String generate(AST ast) {
this.typeTable = ast.typeTable();
pushAssembler();
resolveConstants(ast.constantTable());
resolveGlobalVariables(ast.allGlobalVariables());
resolveFunctions(ast.allFunctions());
for (ConstantEntry ent : ast.constantTable().entries()) {
locateConstant(ent);
}
for (Variable var : ast.allGlobalVariables()) {
locateGlobalVariable(var);
}
for (Function func : ast.allFunctions()) {
locateFunction(func);
}
compileAST(ast);
return popAssembler().toSource();
}
protected void pushAssembler() {
asStack.add(newAssembler());
this.as = (Assembler)asStack.getLast();
this.as = newAssembler();
asStack.add(this.as);
}
protected Assembler popAssembler() {
Assembler poped = (Assembler)asStack.removeLast();
this.as = asStack.isEmpty() ? null : (Assembler)asStack.getLast();
return poped;
Assembler popped = asStack.removeLast();
this.as = asStack.isEmpty() ? null : asStack.getLast();
return popped;
}
protected Assembler newAssembler() {
@ -53,18 +59,26 @@ public class CodeGenerator
_file(ast.fileName());
// .data
_data();
compileGlobalVariables(ast.globalVariables());
for (DefinedVariable gvar : ast.definedGlobalVariables()) {
dataEntry(gvar);
}
if (!ast.constantTable().isEmpty()) {
_section(".rodata");
compileConstants(ast.constantTable());
for (ConstantEntry ent : ast.constantTable()) {
compileStringLiteral(ent);
}
}
// .text
if (ast.functionDefined()) {
_text();
compileFunctions(ast.functions());
for (DefinedFunction func : ast.definedFunctions()) {
compileFunction(func);
}
}
// .bss
compileCommonSymbols(ast.commonSymbols());
for (DefinedVariable var : ast.definedCommonSymbols()) {
compileCommonSymbol(var);
}
// others
if (options.isPICRequired()) {
PICThunk(GOTBaseReg());
@ -72,10 +86,7 @@ public class CodeGenerator
}
// #@@}
protected void resolveConstants(ConstantTable table) {
Iterator ents = table.entries();
while (ents.hasNext()) {
ConstantEntry ent = (ConstantEntry)ents.next();
protected void locateConstant(ConstantEntry ent) {
ent.setLabel(new Label(".LC" + ent.id()));
if (options.isPICRequired()) {
Label offset = new Label(localGOTSymbol(ent.symbol()));
@ -86,26 +97,8 @@ public class CodeGenerator
ent.setAddress(imm(ent.label()));
}
}
}
/**
* Sets memory reference for...
* * public global variables
* * private global variables
* * public common symbols
* * private common symbols
* * static local variables
*/
// #@@range/resolveGlobalVariables
protected void resolveGlobalVariables(Iterator vars) {
while (vars.hasNext()) {
Variable var = (Variable)vars.next();
resolveGlobalVariable(var);
}
}
// #@@}
protected void resolveGlobalVariable(Variable var) {
protected void locateGlobalVariable(Variable var) {
String sym = var.symbol();
MemoryReference mem;
if (options.isPICRequired()) {
@ -124,13 +117,10 @@ public class CodeGenerator
}
}
protected void resolveFunctions(Iterator funcs) {
while (funcs.hasNext()) {
Function func = (Function)funcs.next();
protected void locateFunction(Function func) {
func.setSymbol(functionSymbol(func));
func.setAddress(functionAddress(func));
}
}
protected String functionSymbol(Function func) {
if (func.isDefined()) {
@ -161,16 +151,6 @@ public class CodeGenerator
}
}
/** Generates static variable entries */
// #@@range/compileGlobalVariables{
protected void compileGlobalVariables(Iterator vars) {
while (vars.hasNext()) {
DefinedVariable var = (DefinedVariable)vars.next();
dataEntry(var);
}
}
// #@@}
/** Generates initialized entries */
// #@@range/dataEntry{
protected void dataEntry(DefinedVariable ent) {
@ -215,28 +195,21 @@ public class CodeGenerator
// #@@}
/** Generates BSS entries */
// #@@range/compileCommonSymbols{
protected void compileCommonSymbols(Iterator ents) {
while (ents.hasNext()) {
Variable ent = (Variable)ents.next();
if (ent.isPrivate()) {
_local(csymbol(ent.symbol()));
}
_comm(csymbol(ent.symbol()), ent.allocSize(), ent.alignment());
// #@@range/compileCommonSymbol{
protected void compileCommonSymbol(DefinedVariable var) {
if (var.isPrivate()) {
_local(csymbol(var.symbol()));
}
_comm(csymbol(var.symbol()), var.allocSize(), var.alignment());
}
// #@@}
/** Generates .rodata entry (constant strings) */
// #@@range/compileConstants{
protected void compileConstants(ConstantTable table) {
Iterator ents = table.entries();
while (ents.hasNext()) {
ConstantEntry ent = (ConstantEntry)ents.next();
// #@@range/compileStringLiteral{
protected void compileStringLiteral(ConstantEntry ent) {
label(ent.label());
_string(ent.value());
}
}
// #@@}
// #@@range/tmpsymbol{
@ -317,15 +290,6 @@ public class CodeGenerator
// Compile Function
//
/** Compiles all functions and generates .text section. */
// #@@range/compileFunctions{
protected void compileFunctions(Iterator funcs) {
while (funcs.hasNext()) {
compileFunction((DefinedFunction)funcs.next());
}
}
// #@@}
/** Compiles a function. */
// #@@range/compileFunction{
protected void compileFunction(DefinedFunction func) {
@ -344,10 +308,10 @@ public class CodeGenerator
// #@@}
protected void compileFunctionBody(DefinedFunction func) {
List bodyAsms = compileStmts(func);
List<Assembly> bodyAsms = compileStmts(func);
AsmStatistics stats = AsmStatistics.collect(bodyAsms);
bodyAsms = reduceLabels(bodyAsms, stats);
List saveRegs = usedCalleeSavedRegisters(stats);
List<Register> saveRegs = usedCalleeSavedRegisters(stats);
long lvarBytes = allocateLocalVariables(func.body().scope(),
saveRegs.size());
prologue(func, saveRegs, lvarBytes);
@ -358,7 +322,7 @@ public class CodeGenerator
epilogue(func, saveRegs, lvarBytes);
}
protected List compileStmts(DefinedFunction func) {
protected List<Assembly> compileStmts(DefinedFunction func) {
pushAssembler();
currentFunction = func;
compile(func.body());
@ -367,11 +331,9 @@ public class CodeGenerator
return options.optimizer().optimize(popAssembler().assemblies());
}
protected List reduceLabels(List assemblies, AsmStatistics stats) {
List result = new ArrayList();
Iterator asms = assemblies.iterator();
while (asms.hasNext()) {
Assembly asm = (Assembly)asms.next();
protected List<Assembly> reduceLabels(List<Assembly> assemblies, AsmStatistics stats) {
List<Assembly> result = new ArrayList<Assembly>();
for (Assembly asm : assemblies) {
if (asm.isLabel() && ! stats.doesLabelUsed((Label)asm)) {
;
}
@ -396,11 +358,9 @@ public class CodeGenerator
}
// #@@}
protected List usedCalleeSavedRegisters(AsmStatistics stats) {
List result = new ArrayList();
Iterator regs = calleeSavedRegisters().iterator();
while (regs.hasNext()) {
Register reg = (Register)regs.next();
protected List<Register> usedCalleeSavedRegisters(AsmStatistics stats) {
List<Register> result = new ArrayList<Register>();
for (Register reg : calleeSavedRegisters()) {
if (stats.doesRegisterUsed(reg)) {
result.add(reg);
}
@ -408,11 +368,11 @@ public class CodeGenerator
return result;
}
protected List calleeSavedRegistersCache = null;
protected List<Register> calleeSavedRegistersCache = null;
protected List calleeSavedRegisters() {
protected List<Register> calleeSavedRegisters() {
if (calleeSavedRegistersCache == null) {
ArrayList regs = new ArrayList();
List<Register> regs = new ArrayList<Register>();
regs.add(reg("bx"));
regs.add(reg("si"));
regs.add(reg("di"));
@ -461,15 +421,14 @@ public class CodeGenerator
// #@@range/prologue{
protected void prologue(DefinedFunction func,
List saveRegs, long lvarBytes) {
List<Register> saveRegs,
long lvarBytes) {
push(bp());
mov(sp(), bp());
saveRegisters(saveRegs);
extendStack(lvarBytes);
if (options.isVerboseAsm()) {
Iterator vars = func.localVariables();
while (vars.hasNext()) {
DefinedVariable var = (DefinedVariable)vars.next();
for (DefinedVariable var : func.localVariables()) {
comment("mem " + var.memref().toSource() + ": " + var.name());
}
}
@ -478,7 +437,8 @@ public class CodeGenerator
// #@@range/epilogue{
protected void epilogue(DefinedFunction func,
List savedRegs, long lvarBytes) {
List<Register> savedRegs,
long lvarBytes) {
shrinkStack(lvarBytes);
restoreRegisters(savedRegs);
mov(bp(), sp());
@ -487,20 +447,18 @@ public class CodeGenerator
}
// #@@}
protected void saveRegisters(List saveRegs) {
Iterator regs = saveRegs.iterator();
while (regs.hasNext()) {
Register reg = (Register)regs.next();
protected void saveRegisters(List<Register> saveRegs) {
for (Register reg : saveRegs) {
if (! reg.equals(bp())) { // bp is already saved.
push(reg);
}
}
}
protected void restoreRegisters(List savedRegs) {
Iterator regs = savedRegs.iterator();
while (regs.hasNext()) {
Register reg = (Register)regs.next();
protected void restoreRegisters(List<Register> savedRegs) {
ListIterator<Register> regs = savedRegs.listIterator(savedRegs.size());
while (regs.hasPrevious()) {
Register reg = regs.previous();
if (! reg.equals(bp())) { // bp is going to be restored.
pop(reg);
}
@ -520,10 +478,8 @@ public class CodeGenerator
// #@@}
protected void allocateParameters(DefinedFunction func) {
Iterator vars = func.parameters();
long word = paramStartWord;
while (vars.hasNext()) {
Parameter var = (Parameter)vars.next();
for (Parameter var : func.parameters()) {
if (stackGrowsLower) {
var.setMemref(mem(word * stackWordSize, bp()));
}
@ -539,9 +495,7 @@ public class CodeGenerator
* not determined, assign unfixed IndirectMemoryReference.
*/
protected void allocateLocalVariablesTemp(LocalScope scope) {
Iterator vars = scope.allLocalVariables();
while (vars.hasNext()) {
DefinedVariable var = (DefinedVariable)vars.next();
for (DefinedVariable var : scope.allLocalVariables()) {
var.setMemref(new IndirectMemoryReference(bp()));
}
}
@ -559,9 +513,7 @@ public class CodeGenerator
protected long allocateScope(LocalScope scope, long parentStackLen) {
long len = parentStackLen;
Iterator vars = scope.variables();
while (vars.hasNext()) {
DefinedVariable var = (DefinedVariable)vars.next();
for (DefinedVariable var : scope.localVariables()) {
if (stackGrowsLower) {
len = Assembler.align(len + var.allocSize(), stackAlignment);
fixMemref((IndirectMemoryReference)var.memref(), -len);
@ -574,9 +526,7 @@ public class CodeGenerator
// Allocate local variables in child scopes.
// We allocate child scopes in the same area (overrapped).
long maxLen = len;
Iterator scopes = scope.children();
while (scopes.hasNext()) {
LocalScope s = (LocalScope)scopes.next();
for (LocalScope s : scope.children()) {
long childLen = allocateScope(s, len);
maxLen = Math.max(maxLen, childLen);
}
@ -606,10 +556,9 @@ public class CodeGenerator
*/
public void visit(FuncallNode node) {
// compile function arguments from right to left.
ListIterator args = node.finalArg();
ListIterator<ExprNode> args = node.finalArg();
while (args.hasPrevious()) {
ExprNode arg = (ExprNode)args.previous();
compile(arg);
compile(args.previous());
push(reg("ax"));
}
// call
@ -639,17 +588,14 @@ public class CodeGenerator
//
public void visit(BlockNode node) {
Iterator vars = node.scope().variables();
while (vars.hasNext()) {
DefinedVariable var = (DefinedVariable)vars.next();
for (DefinedVariable var : node.scope().localVariables()) {
if (var.initializer() != null) {
compile(var.initializer());
save(var.type(), reg("ax"), var.memref());
}
}
Iterator stmts = node.stmts();
while (stmts.hasNext()) {
compileStmt((Node)stmts.next());
for (Node stmt : node.stmts()) {
compileStmt(stmt);
}
}
@ -696,26 +642,22 @@ public class CodeGenerator
public void visit(SwitchNode node) {
compile(node.cond());
Type t = typeTable.signedInt();
Iterator cases = node.cases();
while (cases.hasNext()) {
CaseNode caseNode = (CaseNode)cases.next();
if (! caseNode.isDefault()) {
Iterator values = caseNode.values();
while (values.hasNext()) {
IntegerLiteralNode ival = (IntegerLiteralNode)values.next();
for (CaseNode cn : node.cases()) {
if (! cn.isDefault()) {
for (ExprNode ex : cn.values()) {
IntegerLiteralNode ival = (IntegerLiteralNode)ex;
mov(imm(ival.value()), reg("cx"));
cmp(t, reg("cx", t), reg("ax", t));
je(caseNode.beginLabel());
je(cn.beginLabel());
}
}
else {
jmp(caseNode.beginLabel());
jmp(cn.beginLabel());
}
}
jmp(node.endLabel());
cases = node.cases();
while (cases.hasNext()) {
compile((CaseNode)cases.next());
for (CaseNode n : node.cases()) {
compile(n);
}
label(node.endLabel());
}

View File

@ -29,7 +29,9 @@ class CodeGeneratorOptions {
}
class NullOptimizer implements AsmOptimizer {
public List optimize(List assemblies) { return assemblies; }
public List<Assembly> optimize(List<Assembly> asms) {
return asms;
}
}
public void generateVerboseAsm() {

View File

@ -27,7 +27,7 @@ public class Compiler {
public void commandMain(String[] origArgs) {
Options opts = new Options(defaultTypeTable(), new LibraryLoader());
List srcs = null;
List<SourceFile> srcs = null;
try {
srcs = opts.parse(Arrays.asList(origArgs));
}
@ -37,10 +37,8 @@ public class Compiler {
System.exit(1);
}
if (opts.isMode("--check-syntax")) {
Iterator inputs = srcs.iterator();
boolean failed = false;
while (inputs.hasNext()) {
SourceFile src = (SourceFile)inputs.next();
for (SourceFile src : srcs) {
if (isValidSyntax(src, opts)) {
System.out.println(src.name() + ": Syntax OK");
}
@ -53,9 +51,7 @@ public class Compiler {
}
else {
try {
Iterator inputs = srcs.iterator();
while (inputs.hasNext()) {
SourceFile src = (SourceFile)inputs.next();
for (SourceFile src : srcs) {
compileFile(src, opts);
}
if (! opts.isLinkRequired()) System.exit(0);
@ -134,9 +130,8 @@ public class Compiler {
}
}
protected void dumpTokens(Iterator tokens, PrintStream s) {
while (tokens.hasNext()) {
CflatToken t = (CflatToken)tokens.next();
protected void dumpTokens(CflatToken tokens, PrintStream s) {
for (CflatToken t : tokens) {
printPair(t.kindName(), t.dumpedImage(), s);
}
}
@ -152,16 +147,14 @@ public class Compiler {
}
protected Node findStmt(AST ast) {
Iterator funcs = ast.functions();
while (funcs.hasNext()) {
DefinedFunction f = (DefinedFunction)funcs.next();
for (DefinedFunction f : ast.definedFunctions()) {
if (f.name().equals("main")) {
Iterator stmts = f.body().stmts();
while (stmts.hasNext()) {
return (Node)stmts.next();
}
Node stmt = f.body().stmts().get(0);
if (stmt == null) {
errorExit("main() has no stmt");
}
return stmt;
}
}
errorExit("source file does not contains main()");
return null; // never reach
@ -197,7 +190,7 @@ public class Compiler {
protected void assemble(String srcPath,
String destPath,
Options opts) throws IPCException {
List cmd = new ArrayList();
List<Object> cmd = new ArrayList<Object>();
cmd.add("as");
cmd.addAll(opts.asOptions());
cmd.add("-o");
@ -213,7 +206,7 @@ public class Compiler {
static final protected String C_RUNTIME_FINI = "/usr/lib/crtn.o";
protected void generateExecutable(Options opts) throws IPCException {
List cmd = new ArrayList();
List<Object> cmd = new ArrayList<Object>();
cmd.add("ld");
cmd.add("-dynamic-linker");
cmd.add(DYNAMIC_LINKER);
@ -240,7 +233,7 @@ public class Compiler {
}
protected void generateSharedLibrary(Options opts) throws IPCException {
List cmd = new ArrayList();
List<Object> cmd = new ArrayList<Object>();
cmd.add("ld");
cmd.add("-shared");
if (! opts.noStartFiles()) {
@ -259,12 +252,12 @@ public class Compiler {
invoke(cmd, opts.isVerboseMode());
}
protected void invoke(List cmdArgs, boolean debug) throws IPCException {
protected void invoke(List<Object> cmdArgs, boolean debug) throws IPCException {
if (debug) {
dumpCommand(cmdArgs.iterator());
dumpCommand(cmdArgs);
}
try {
String[] cmd = stringListToArray(cmdArgs);
String[] cmd = getStrings(cmdArgs);
Process proc = Runtime.getRuntime().exec(cmd);
proc.waitFor();
passThrough(proc.getInputStream());
@ -285,23 +278,20 @@ public class Compiler {
}
}
protected String[] stringListToArray(List list) {
protected String[] getStrings(List<Object> list) {
String[] a = new String[list.size()];
int idx = 0;
Iterator it = list.iterator();
while (it.hasNext()) {
Object o = it.next();
for (Object o : list) {
a[idx++] = o.toString();
}
return a;
}
protected void dumpCommand(Iterator args) {
protected void dumpCommand(List<Object> args) {
String sep = "";
while (args.hasNext()) {
String arg = args.next().toString();
for (Object arg : args) {
System.out.print(sep); sep = " ";
System.out.print(arg);
System.out.print(arg.toString());
}
System.out.println("");
}

View File

@ -12,18 +12,12 @@ class DereferenceChecker extends Visitor {
}
public void check(AST ast) throws SemanticException {
Iterator vars = ast.variables();
while (vars.hasNext()) {
DefinedVariable var = (DefinedVariable)vars.next();
for (DefinedVariable var : ast.definedVariables()) {
checkVariable(var);
}
Iterator funcs = ast.functions();
while (funcs.hasNext()) {
DefinedFunction f = (DefinedFunction)funcs.next();
for (DefinedFunction f : ast.definedFunctions()) {
check(f.body());
}
if (errorHandler.errorOccured()) {
throw new SemanticException("compile failed.");
}
@ -38,15 +32,10 @@ class DereferenceChecker extends Visitor {
//
public void visit(BlockNode node) {
Iterator vars = node.variables();
while (vars.hasNext()) {
DefinedVariable var = (DefinedVariable)vars.next();
for (DefinedVariable var : node.variables()) {
checkVariable(var);
}
Iterator stmts = node.stmts();
while (stmts.hasNext()) {
Node stmt = (Node)stmts.next();
for (Node stmt : node.stmts()) {
try {
check(stmt);
}
@ -79,7 +68,7 @@ class DereferenceChecker extends Visitor {
public void visit(OpAssignNode node) {
super.visit(node);
checkAssignment(node);
// check as operator
// FIXME: check as operator
}
protected void checkAssignment(AbstractAssignNode node) {

View File

@ -7,8 +7,8 @@ import java.util.*;
public class JumpResolver extends Visitor {
// #@@range/ctor{
protected ErrorHandler errorHandler;
protected LinkedList breakTargetStack;
protected LinkedList continueTargetStack;
protected LinkedList<BreakableStmt> breakTargetStack;
protected LinkedList<ContinueableStmt> continueTargetStack;
protected DefinedFunction currentFunction;
public JumpResolver(ErrorHandler h) {
@ -18,13 +18,12 @@ public class JumpResolver extends Visitor {
// #@@range/resolve{
public void resolve(AST ast) throws SemanticException {
breakTargetStack = new LinkedList();
continueTargetStack = new LinkedList();
Iterator funcs = ast.functions();
while (funcs.hasNext()) {
currentFunction = (DefinedFunction)funcs.next();
resolve(currentFunction.body());
currentFunction.checkJumpLinks(errorHandler);
breakTargetStack = new LinkedList<BreakableStmt>();
continueTargetStack = new LinkedList<ContinueableStmt>();
for (DefinedFunction f : ast.definedFunctions()) {
currentFunction = f;
resolve(f.body());
f.checkJumpLinks(errorHandler);
}
if (errorHandler.errorOccured()) {
throw new SemanticException("compile failed.");
@ -83,7 +82,7 @@ public class JumpResolver extends Visitor {
"break from out of while/do-while/for/switch");
return;
}
BreakableStmt target = (BreakableStmt)breakTargetStack.getLast();
BreakableStmt target = breakTargetStack.getLast();
node.setTargetLabel(target.endLabel());
}
// #@@}
@ -95,8 +94,7 @@ public class JumpResolver extends Visitor {
"continue from out of while/do-while/for");
return;
}
ContinueableStmt target =
(ContinueableStmt)continueTargetStack.getLast();
ContinueableStmt target = continueTargetStack.getLast();
node.setTargetLabel(target.continueLabel());
}
// #@@}

View File

@ -6,12 +6,12 @@ import java.util.*;
import java.io.*;
public class LibraryLoader {
protected List loadPath;
protected LinkedList loadingLibraries; // LinkedList<String>
protected Map loadedLibraries; // Map<String, Boolean>
protected List<String> loadPath;
protected LinkedList<String> loadingLibraries;
protected Map<String, Declarations> loadedLibraries;
static public List defaultLoadPath() {
List pathes = new ArrayList();
static public List<String> defaultLoadPath() {
List<String> pathes = new ArrayList<String>();
pathes.add(".");
return pathes;
}
@ -20,10 +20,10 @@ public class LibraryLoader {
this(defaultLoadPath());
}
public LibraryLoader(List loadPath) {
public LibraryLoader(List<String> loadPath) {
this.loadPath = loadPath;
this.loadingLibraries = new LinkedList();
this.loadedLibraries = new HashMap();
this.loadingLibraries = new LinkedList<String>();
this.loadedLibraries = new HashMap<String, Declarations>();
}
public void addLoadPath(String path) {
@ -38,7 +38,7 @@ public class LibraryLoader {
+ ": " + libid);
}
loadingLibraries.addLast(libid); // stop recursive import
Declarations decls = (Declarations)loadedLibraries.get(libid);
Declarations decls = loadedLibraries.get(libid);
if (decls != null) {
// Already loaded import file. Returns cached declarations.
return decls;
@ -51,9 +51,7 @@ public class LibraryLoader {
public File searchLibrary(String libid) throws FileException {
try {
Iterator pathes = loadPath.iterator();
while (pathes.hasNext()) {
String path = (String)pathes.next();
for (String path : loadPath) {
File file = new File(path + "/" + libPath(libid) + ".hb");
if (file.exists()) {
return file;

View File

@ -7,7 +7,7 @@ public class LocalReferenceResolver extends Visitor {
// #@@range/ctor{
protected ErrorHandler errorHandler;
protected ToplevelScope toplevel;
protected LinkedList scopeStack;
protected LinkedList<Scope> scopeStack;
protected ConstantTable constantTable;
public LocalReferenceResolver(ErrorHandler h) {
@ -22,17 +22,21 @@ public class LocalReferenceResolver extends Visitor {
// #@@range/resolve{
public void resolve(AST ast) throws SemanticException {
toplevel = ast.scope();
scopeStack = new LinkedList();
scopeStack = new LinkedList<Scope>();
scopeStack.add(toplevel);
constantTable = ast.constantTable();
// #@@range/declareToplevel{
declareToplevelEntities(ast.declarations());
declareToplevelEntities(ast.entities());
for (Entity decl : ast.declarations()) {
toplevel.declareEntity(decl);
}
for (Entity ent : ast.entities()) {
toplevel.declareEntity(ent);
}
// #@@}
// #@@range/resolveRefs{
resolveGvarInitializers(ast.variables());
resolveFunctions(ast.functions());
resolveGvarInitializers(ast.definedVariables());
resolveFunctions(ast.definedFunctions());
// #@@}
toplevel.checkReferences(errorHandler);
if (errorHandler.errorOccured()) {
@ -41,29 +45,19 @@ public class LocalReferenceResolver extends Visitor {
}
// #@@}
// #@@range/declareToplevelEntities{
protected void declareToplevelEntities(Iterator decls) {
while (decls.hasNext()) {
toplevel.declareEntity((Entity)decls.next());
}
}
// #@@}
// #@@range/resolveGvarInitializers{
protected void resolveGvarInitializers(Iterator vars) {
while (vars.hasNext()) {
DefinedVariable var = (DefinedVariable)vars.next();
if (var.hasInitializer()) {
resolve(var.initializer());
protected void resolveGvarInitializers(List<DefinedVariable> gvars) {
for (DefinedVariable gvar : gvars) {
if (gvar.hasInitializer()) {
resolve(gvar.initializer());
}
}
}
// #@@}
// #@@range/resolveFunctions{
protected void resolveFunctions(Iterator funcs) {
while (funcs.hasNext()) {
DefinedFunction func = (DefinedFunction)funcs.next();
protected void resolveFunctions(List<DefinedFunction> funcs) {
for (DefinedFunction func : funcs) {
pushScope(func.parameters());
resolve(func.body());
func.setScope(popScope());
@ -80,15 +74,14 @@ public class LocalReferenceResolver extends Visitor {
// #@@}
// #@@range/pushScope{
protected void pushScope(Iterator vars) {
protected void pushScope(List<? extends DefinedVariable> vars) {
LocalScope scope = new LocalScope(currentScope());
while (vars.hasNext()) {
DefinedVariable var = (DefinedVariable)vars.next();
for (DefinedVariable var : vars) {
if (scope.isDefinedLocally(var.name())) {
error(var, "duplicated variable in scope: " + var.name());
}
else {
scope.declareEntity(var);
scope.defineVariable(var);
}
}
scopeStack.addLast(scope);
@ -103,7 +96,7 @@ public class LocalReferenceResolver extends Visitor {
// #@@range/currentScope{
protected Scope currentScope() {
return (Scope)scopeStack.getLast();
return scopeStack.getLast();
}
// #@@}

View File

@ -14,10 +14,10 @@ class Options {
protected boolean verbose;
protected boolean debugParser;
protected CodeGeneratorOptions genOptions;
protected List asOptions; // List<String>
protected List<String> asOptions;
protected boolean generatingSharedLibrary;
protected boolean generatingPIE;
protected List ldArgs; // List<LdArg>
protected List<LdArg> ldArgs;
protected boolean noStartFiles = false;
protected boolean noDefaultLibs = false;
@ -25,10 +25,10 @@ class Options {
this.typeTable = typeTable;
this.loader = loader;
this.genOptions = new CodeGeneratorOptions();
this.asOptions = new ArrayList();
this.asOptions = new ArrayList<String>();
this.generatingSharedLibrary = false;
this.generatingPIE = false;
this.ldArgs = new ArrayList();
this.ldArgs = new ArrayList<LdArg>();
}
public boolean isMode(String m) {
@ -44,12 +44,12 @@ class Options {
}
static final protected String defaultMode = "link";
static protected List modeLevels;
static protected List<String> modeLevels;
static final protected int MODE_LEVEL_ASSEMBLE;
static final protected int MODE_LEVEL_LINK;
static {
modeLevels = new ArrayList();
modeLevels = new ArrayList<String>();
modeLevels.add("--check-syntax");
modeLevels.add("--dump-tokens");
modeLevels.add("--dump-ast");
@ -86,23 +86,20 @@ class Options {
if (outputFileName != null) {
return outputFileName;
}
List srcs = sourceFiles();
List<SourceFile> srcs = sourceFiles();
if (srcs.size() == 1) {
SourceFile src = (SourceFile)srcs.get(0);
return src.linkedFileName(this, newExt);
return srcs.get(0).linkedFileName(this, newExt);
}
else {
return "a.out";
}
}
protected List sourceFiles() {
Iterator args = ldArgs.iterator();
List result = new ArrayList();
while (args.hasNext()) {
LdArg arg = (LdArg)args.next();
protected List<SourceFile> sourceFiles() {
List<SourceFile> result = new ArrayList<SourceFile>();
for (LdArg arg : ldArgs) {
if (arg.isSourceFile()) {
result.add(arg);
result.add((SourceFile)arg);
}
}
return result;
@ -132,8 +129,7 @@ class Options {
return genOptions;
}
// List<String>
public List asOptions() {
public List<String> asOptions() {
return this.asOptions;
}
@ -146,7 +142,7 @@ class Options {
}
// List<ldArg>
public List ldArgs() {
public List<LdArg> ldArgs() {
return this.ldArgs;
}
@ -159,11 +155,11 @@ class Options {
}
/** Returns List<SourceFile>. */
public List parse(List argsList) {
ListIterator args = argsList.listIterator();
List srcs = new ArrayList();
public List<SourceFile> parse(List<String> argsList) {
List<SourceFile> srcs = new ArrayList<SourceFile>();
ListIterator<String> args = argsList.listIterator();
while (args.hasNext()) {
String arg = (String)args.next();
String arg = args.next();
if (arg.equals("--")) {
// "--" Stops command line processing
break;
@ -245,9 +241,7 @@ class Options {
noDefaultLibs = true;
}
else if (arg.startsWith("-Wl,")) {
Iterator opts = parseCommaSeparatedOptions(arg).iterator();
while (opts.hasNext()) {
String opt = (String)opts.next();
for (String opt : parseCommaSeparatedOptions(arg)) {
ldArgs.add(new LdOption(opt));
}
}
@ -277,8 +271,7 @@ class Options {
}
// args has more arguments when "--" is appeared.
while (args.hasNext()) {
String arg = (String)args.next();
addSourceFile(srcs, ldArgs, arg);
addSourceFile(srcs, ldArgs, args.next());
}
if (srcs.isEmpty()) parseError("no input file");
if (mode == null) {
@ -294,14 +287,14 @@ class Options {
throw new OptionParseError(msg);
}
protected void addSourceFile(List srcs, List ldArgs, String sourceName) {
protected void addSourceFile(List<SourceFile> srcs, List<LdArg> ldArgs, String sourceName) {
SourceFile src = new SourceFile(sourceName);
srcs.add(src);
// Original argument order does matter when linking.
ldArgs.add(src);
}
protected String getOptArg(String opt, ListIterator args) {
protected String getOptArg(String opt, ListIterator<String> args) {
String path = opt.substring(2);
if (path.length() != 0) { // -Ipath
return path;
@ -311,16 +304,16 @@ class Options {
}
}
protected String nextArg(String opt, ListIterator args) {
protected String nextArg(String opt, ListIterator<String> args) {
if (! args.hasNext()) {
parseError("missing argument for " + opt);
}
return (String)args.next();
return args.next();
}
/** "-Wl,-rpath,/usr/local/lib" -> ["-rpath", "/usr/local/lib"] */
protected List parseCommaSeparatedOptions(String opt) {
List opts = arrayToList(opt.split(","));
protected List<String> parseCommaSeparatedOptions(String opt) {
List<String> opts = Arrays.asList(opt.split(","));
opts.remove(0); // remove "-Wl" etc.
if (opts.isEmpty()) {
parseError("missing argument for " + opt);
@ -328,14 +321,6 @@ class Options {
return opts;
}
protected List arrayToList(Object[] ary) {
List result = new ArrayList();
for (int i = 0; i < ary.length; i++) {
result.add(ary[i]);
}
return result;
}
public void printUsage(PrintStream out) {
out.println("Usage: cbc [options] file...");
out.println("Global Options:");

View File

@ -21,14 +21,10 @@ class TypeChecker extends Visitor {
// #@@range/check_AST{
public void check(AST ast) throws SemanticException {
this.typeTable = ast.typeTable();
Iterator vars = ast.variables();
while (vars.hasNext()) {
DefinedVariable var = (DefinedVariable)vars.next();
for (DefinedVariable var : ast.definedVariables()) {
checkVariable(var);
}
Iterator funcs = ast.functions();
while (funcs.hasNext()) {
DefinedFunction f = (DefinedFunction)funcs.next();
for (DefinedFunction f : ast.definedFunctions()) {
checkReturnType(f);
checkParamTypes(f);
check(f.body());
@ -42,14 +38,11 @@ class TypeChecker extends Visitor {
protected void checkReturnType(DefinedFunction f) {
if (isInvalidReturnType(f.returnType())) {
error(f, "returns invalid type: " + f.returnType());
return;
}
}
protected void checkParamTypes(DefinedFunction f) {
Iterator params = f.parameters();
while (params.hasNext()) {
Parameter param = (Parameter)params.next();
for (Parameter param : f.parameters()) {
if (isInvalidParameterType(param.type())) {
error(param, "invalid parameter type: " + param.type());
}
@ -61,14 +54,10 @@ class TypeChecker extends Visitor {
//
public void visit(BlockNode node) {
Iterator vars = node.variables();
while (vars.hasNext()) {
DefinedVariable var = (DefinedVariable)vars.next();
for (DefinedVariable var : node.variables()) {
checkVariable(var);
}
Iterator stmts = node.stmts();
while (stmts.hasNext()) {
Node n = (Node)stmts.next();
for (Node n : node.stmts()) {
if (n instanceof ExprNode) {
ExprNode expr = (ExprNode)n;
if (isInvalidStatementType(expr.type())) {
@ -468,17 +457,14 @@ class TypeChecker extends Visitor {
return;
}
// Check type of only mandatory parameters.
Iterator params = type.paramTypes();
Iterator args = node.arguments();
List newArgs = new ArrayList();
while (params.hasNext()) {
Type param = (Type)params.next();
ExprNode arg = (ExprNode)args.next();
Iterator<ExprNode> args = node.arguments().iterator();
List<ExprNode> newArgs = new ArrayList<ExprNode>();
for (Type param : type.paramTypes()) {
ExprNode arg = args.next();
newArgs.add(checkRHS(arg) ? implicitCast(param, arg) : arg);
}
while (args.hasNext()) {
ExprNode arg = (ExprNode)args.next();
newArgs.add(arg);
newArgs.add(args.next());
}
node.replaceArgs(newArgs);
}

View File

@ -25,15 +25,14 @@ public class TypeResolver extends Visitor {
// #@@}
// #@@range/resolveNodeList{
protected void resolveNodeList(Iterator nodes) {
protected void resolveNodeList(List<? extends Node> nodes) {
visitNodeList(nodes);
}
// #@@}
// #@@range/defineTypes{
private void defineTypes(Iterator deftypes) {
while (deftypes.hasNext()) {
TypeDefinition def = (TypeDefinition)deftypes.next();
private void defineTypes(List<TypeDefinition> deftypes) {
for (TypeDefinition def : deftypes) {
if (typeTable.isDefined(def.typeRef())) {
error(def, "duplicated type definition: " + def.typeRef());
}
@ -69,10 +68,8 @@ public class TypeResolver extends Visitor {
if (ct == null) {
throw new Error("cannot intern struct/union: " + def.name());
}
Iterator membs = ct.members();
while (membs.hasNext()) {
Slot slot = (Slot)membs.next();
bindType(slot.typeNode());
for (Slot s : ct.members()) {
bindType(s.typeNode());
}
}
// #@@}
@ -109,9 +106,7 @@ public class TypeResolver extends Visitor {
// #@@range/resolveFunctionHeader{
protected void resolveFunctionHeader(Function func) {
bindType(func.typeNode());
Iterator params = func.parameters();
while (params.hasNext()) {
Parameter param = (Parameter)params.next();
for (Parameter param : func.parameters()) {
bindType(param.typeNode());
}
}

View File

@ -10,9 +10,8 @@ abstract public class Visitor implements ASTVisitor {
node.accept(this);
}
protected void visitNodeList(Iterator ns) {
while (ns.hasNext()) {
Node n = (Node)ns.next();
protected void visitNodeList(List<? extends Node> nodes) {
for (Node n : nodes) {
visitNode(n);
}
}
@ -50,9 +49,7 @@ abstract public class Visitor implements ASTVisitor {
//
public void visit(BlockNode node) {
Iterator vars = node.variables();
while (vars.hasNext()) {
DefinedVariable var = (DefinedVariable)vars.next();
for (DefinedVariable var : node.variables()) {
visit(var);
}
visitNodeList(node.stmts());

View File

@ -76,7 +76,7 @@ public class Parser {
protected LibraryLoader loader;
protected ErrorHandler errorHandler;
protected LabelPool labelPool;
protected Set knownTypedefs;
protected Set<String> knownTypedefs;
// #@@}
// #@@range/ctor1{
@ -94,7 +94,7 @@ public class Parser {
this.loader = loader;
this.errorHandler = errorHandler;
this.labelPool = new LabelPool();
this.knownTypedefs = new HashSet();
this.knownTypedefs = new HashSet<String>();
if (debug) {
enable_tracing();
}
@ -133,9 +133,8 @@ public class Parser {
}
}
private void addKnownTypedefs(Iterator typedefs) {
while (typedefs.hasNext()) {
TypedefNode n = (TypedefNode)typedefs.next();
private void addKnownTypedefs(List<TypedefNode> typedefs) {
for (TypedefNode n : typedefs) {
addType(n.name());
}
}
@ -429,7 +428,7 @@ Declarations import_stmts():
Declarations decls = loader.loadLibrary(libid, errorHandler);
if (decls != null) {
impdecls.add(decls);
addKnownTypedefs(decls.typedefs().iterator());
addKnownTypedefs(decls.typedefs());
}
}
catch (CompileException ex) {
@ -464,7 +463,7 @@ Declarations top_defs():
{
Declarations decls = new Declarations();
DefinedFunction defun;
List defvars;
List<DefinedVariable> defvars;
StructNode defstruct;
UnionNode defunion;
TypedefNode typedef;
@ -485,9 +484,9 @@ Declarations top_defs():
// #@@}
// #@@range/defvars{
List defvars():
List<DefinedVariable> defvars():
{
List defs = new ArrayList();
List<DefinedVariable> defs = new ArrayList<DefinedVariable>();
boolean priv;
TypeNode type;
String name;
@ -523,9 +522,9 @@ DefinedFunction defun():
{
priv=storage() ref=typeref() n=name() "(" ps=params() ")" body=block()
{
Params ptypes = ps.typeRefs();
ParamTypeRefs paramref = ps.parametersTypeRef();
TypeNode t = new TypeNode(new PointerTypeRef(
new FunctionTypeRef(ref, ptypes)));
new FunctionTypeRef(ref, paramref)));
return new DefinedFunction(labelPool, priv, t, n, ps, body);
}
}
@ -543,16 +542,16 @@ boolean storage():
Params params():
{
Token t;
FixedParams params;
Params params;
}
{
LOOKAHEAD(<VOID> ")")
t=<VOID>
{
return new FixedParams(location(t), new ArrayList());
return new Params(location(t), new ArrayList<Parameter>());
}
| params=fixedparams()
["," "..." { return new VarParams(params); }]
["," "..." { params.acceptVarargs(); }]
{
return params;
}
@ -560,16 +559,16 @@ Params params():
// #@@}
// #@@range/fixedparams{
FixedParams fixedparams():
Params fixedparams():
{
List params = new ArrayList();
List<Parameter> params = new ArrayList<Parameter>();
Parameter param, param1;
}
{
param1=param() { params.add(param1); }
( LOOKAHEAD(2) "," param=param() { params.add(param); } )*
{
return new FixedParams(param1.location(), params);
return new Params(param1.location(), params);
}
}
// #@@}
@ -589,8 +588,8 @@ Parameter param():
BlockNode block():
{
Token t;
List vars;
List stmts;
List<DefinedVariable> vars;
List<Node> stmts;
}
{
t="{" vars=defvar_list() stmts=stmts() "}"
@ -602,10 +601,10 @@ BlockNode block():
// #@@range/defvar_list{
List defvar_list():
List<DefinedVariable> defvar_list():
{
List result = new ArrayList();
List vars;
List<DefinedVariable> result = new ArrayList<DefinedVariable>();
List<DefinedVariable> vars;
}
{
( vars=defvars() { result.addAll(vars); } )*
@ -620,7 +619,7 @@ StructNode defstruct():
{
Token t;
String n;
List membs;
List<Slot> membs;
}
{
t=<STRUCT> n=name() membs=member_list() ";"
@ -634,7 +633,7 @@ UnionNode defunion():
{
Token t;
String n;
List membs;
List<Slot> membs;
}
{
t=<UNION> n=name() membs=member_list() ";"
@ -644,9 +643,9 @@ UnionNode defunion():
}
// #@@range/member_list{
List member_list():
List<Slot> member_list():
{
List membs = new ArrayList();
List<Slot> membs = new ArrayList<Slot>();
Slot s;
}
{
@ -678,9 +677,9 @@ UndefinedFunction funcdecl():
{
<EXTERN> ref=typeref() n=name() "(" ps=params() ")" ";"
{
Params ptyperefs = ps.typeRefs();
ParamTypeRefs paramref = ps.parametersTypeRef();
TypeNode t = new TypeNode(new PointerTypeRef(
new FunctionTypeRef(ref, ptyperefs)));
new FunctionTypeRef(ref, paramref)));
return new UndefinedFunction(t, n, ps);
}
}
@ -711,7 +710,7 @@ TypeRef typeref():
{
TypeRef ref;
Token t;
Params params;
ParamTypeRefs params;
}
{
ref=typeref_base()
@ -740,16 +739,16 @@ TypeRef typeref():
// #@@}
// #@@range/param_typerefs{
Params param_typerefs():
{ FixedParams params; }
ParamTypeRefs param_typerefs():
{ ParamTypeRefs params; }
{
LOOKAHEAD(<VOID> ")")
<VOID>
{
return new FixedParams(new ArrayList());
return new ParamTypeRefs(new ArrayList<TypeRef>());
}
| params=fixedparam_typerefs()
[ "," "..." { return new VarParams(params); } ]
[ "," "..." { params.acceptVarargs(); }]
{
return params;
}
@ -757,16 +756,16 @@ Params param_typerefs():
// #@@}
// #@@range/fixedparam_typerefs{
FixedParams fixedparam_typerefs():
ParamTypeRefs fixedparam_typerefs():
{
List refs = new ArrayList();
List<TypeRef> refs = new ArrayList<TypeRef>();
TypeRef ref;
}
{
ref=typeref() { refs.add(ref); }
( LOOKAHEAD(2) "," ref=typeref() { refs.add(ref); } )*
{
return new FixedParams(refs);
return new ParamTypeRefs(refs);
}
}
// #@@}
@ -816,9 +815,9 @@ TypedefNode typedef():
// #@@}
// #@@range/stmts{
List stmts():
List<Node> stmts():
{
List ss = new ArrayList();
List<Node> ss = new ArrayList<Node>();
Node s;
}
{
@ -928,7 +927,7 @@ SwitchNode switch_stmt():
{
Token t;
ExprNode cond;
List bodies;
List<CaseNode> bodies;
}
{
t=<SWITCH> "(" cond=expr() ")" "{" bodies=case_clauses() "}"
@ -937,10 +936,10 @@ SwitchNode switch_stmt():
}
}
List case_clauses():
List<CaseNode> case_clauses():
{
List clauses = new ArrayList();
Node n;
List<CaseNode> clauses = new ArrayList<CaseNode>();
CaseNode n;
}
{
(n=case_clause() { clauses.add(n); })*
@ -952,7 +951,7 @@ List case_clauses():
CaseNode case_clause():
{
List values;
List<ExprNode> values;
BlockNode body;
}
{
@ -962,9 +961,9 @@ CaseNode case_clause():
}
}
List cases():
List<ExprNode> cases():
{
List values = new ArrayList();
List<ExprNode> values = new ArrayList<ExprNode>();
ExprNode n;
}
{
@ -980,25 +979,26 @@ CaseNode default_clause():
<DEFAULT_> ":" body=case_body()
{
return new CaseNode(body.location(), labelPool,
new ArrayList(), body);
new ArrayList<ExprNode>(), body);
}
}
BlockNode case_body():
{
LinkedList ss = new LinkedList();
LinkedList<Node> stmts = new LinkedList<Node>();
Node s;
}
{
(s=stmt() { if (s != null) ss.add(s); })+
(s=stmt() { if (s != null) stmts.add(s); })+
{
// last stmt of case clause must be break stmt.
if (! (ss.getLast() instanceof BreakNode)) {
if (! (stmts.getLast() instanceof BreakNode)) {
throw new ParseException(
"missing break statement at the last of case clause");
}
return new BlockNode(((Node)ss.get(0)).location(),
new ArrayList(), ss);
return new BlockNode(stmts.get(0).location(),
new ArrayList<DefinedVariable>(),
stmts);
}
}
@ -1244,7 +1244,7 @@ ExprNode postfix():
{
ExprNode expr, idx;
String memb;
List args;
List<ExprNode> args;
}
{
expr=primary()
@ -1270,9 +1270,9 @@ String name():
// #@@}
// #@@range/args{
List args():
List<ExprNode> args():
{
List args = new ArrayList();
List<ExprNode> args = new ArrayList<ExprNode>();
ExprNode arg;
}
{

View File

@ -6,12 +6,12 @@ import java.util.*;
import java.lang.reflect.*;
abstract public class CompositeType extends NamedType {
protected List members; // List<Slot>
protected List<Slot> members;
protected long cachedSize;
protected long cachedAlign;
protected boolean isRecursiveChecked;
public CompositeType(String name, List membs, Location loc) {
public CompositeType(String name, List<Slot> membs, Location loc) {
super(name, loc);
this.members = membs;
this.cachedSize = Type.sizeUnknown;
@ -40,12 +40,9 @@ abstract public class CompositeType extends NamedType {
if (isUnion() && !other.isUnion()) return false;
CompositeType otherType = other.getCompositeType();
if (members.size() != other.size()) return false;
Iterator types = memberTypes();
Iterator otherTypes = otherType.memberTypes();
while (types.hasNext()) {
if (! compareTypesBy(cmpMethod,
(Type)types.next(),
(Type)otherTypes.next())) {
Iterator<Type> otherTypes = otherType.memberTypes().iterator();
for (Type t : memberTypes()) {
if (! compareTypesBy(cmpMethod, t, otherTypes.next())) {
return false;
}
}
@ -84,19 +81,16 @@ abstract public class CompositeType extends NamedType {
return cachedAlign;
}
/** Returns a List<Slot> of members. */
public Iterator members() {
return members.iterator();
public List<Slot> members() {
return members;
}
/** Returns a List<Type> of members. */
public Iterator memberTypes() {
Iterator membs = members.iterator();
List result = new ArrayList();
while (membs.hasNext()) {
result.add(((Slot)membs.next()).type());
public List<Type> memberTypes() {
List<Type> result = new ArrayList<Type>();
for (Slot s : members) {
result.add(s.type());
}
return result.iterator();
return result;
}
public boolean hasMember(String name) {
@ -127,9 +121,7 @@ abstract public class CompositeType extends NamedType {
}
public Slot get(String name) {
Iterator membs = members.iterator();
while (membs.hasNext()) {
Slot s = (Slot)membs.next();
for (Slot s : members) {
if (s.name().equals(name)) {
return s;
}

View File

@ -4,9 +4,9 @@ import java.util.*;
public class FunctionType extends Type {
protected Type returnType;
protected Params paramTypes;
protected ParamTypes paramTypes;
public FunctionType(Type ret, Params partypes) {
public FunctionType(Type ret, ParamTypes partypes) {
returnType = ret;
paramTypes = partypes;
}
@ -52,8 +52,8 @@ public class FunctionType extends Type {
* Returns iterator of mandatory parameter types.
* This method does NOT include types for varargs.
*/
public Iterator paramTypes() {
return paramTypes.parameters();
public List<Type> paramTypes() {
return paramTypes.types();
}
public long alignment() {
@ -68,9 +68,7 @@ public class FunctionType extends Type {
StringBuffer buf = new StringBuffer();
buf.append(returnType.toString());
buf.append(" (*)(");
Iterator params = paramTypes.parameters();
while (params.hasNext()) {
Type t = (Type)params.next();
for (Type t : paramTypes.types()) {
buf.append(t.toString());
}
buf.append(")");

View File

@ -4,9 +4,9 @@ import java.util.*;
public class FunctionTypeRef extends TypeRef {
protected TypeRef returnType;
protected Params params;
protected ParamTypeRefs params;
public FunctionTypeRef(TypeRef returnType, Params params) {
public FunctionTypeRef(TypeRef returnType, ParamTypeRefs params) {
super(returnType.location());
this.returnType = returnType;
this.params = params;
@ -17,17 +17,20 @@ public class FunctionTypeRef extends TypeRef {
}
public boolean equals(Object other) {
if (!(other instanceof FunctionTypeRef)) return false;
FunctionTypeRef ref = (FunctionTypeRef)other;
return returnType.equals(ref.returnType()) &&
params.equals(ref.params());
return (other instanceof FunctionTypeRef)
&& equals((FunctionTypeRef)other);
}
public boolean equals(FunctionTypeRef other) {
return returnType.equals(other.returnType())
&& params.equals(other.params());
}
public TypeRef returnType() {
return returnType;
}
public Params params() {
public ParamTypeRefs params() {
return params;
}
@ -35,10 +38,8 @@ public class FunctionTypeRef extends TypeRef {
StringBuffer buf = new StringBuffer();
buf.append(returnType.toString());
buf.append(" (");
Iterator params = this.params.parameters();
String sep = "";
while (params.hasNext()) {
TypeRef ref = (TypeRef)params.next();
for (TypeRef ref : this.params.typerefs()) {
buf.append(sep);
buf.append(ref.toString());
sep = ", ";

View File

@ -0,0 +1,36 @@
package net.loveruby.cflat.type;
import net.loveruby.cflat.ast.ParamSlots;
import net.loveruby.cflat.ast.Location;
import java.util.*;
public class ParamTypeRefs extends ParamSlots<TypeRef> {
public ParamTypeRefs(List<TypeRef> paramDescs) {
super(paramDescs);
}
public ParamTypeRefs(Location loc, List<TypeRef> paramDescs, boolean vararg) {
super(loc, paramDescs, vararg);
}
public List<TypeRef> typerefs() {
return paramDescriptors;
}
public ParamTypes internTypes(TypeTable table) {
List<Type> types = new ArrayList<Type>();
for (TypeRef ref : paramDescriptors) {
types.add(table.get(ref));
}
return new ParamTypes(location, types, vararg);
}
public boolean equals(Object other) {
return (other instanceof ParamTypeRefs)
&& equals((ParamTypeRefs)other);
}
public boolean equals(ParamTypeRefs other) {
return vararg == other.vararg
&& paramDescriptors.equals(other.paramDescriptors);
}
}

View File

@ -0,0 +1,35 @@
package net.loveruby.cflat.type;
import net.loveruby.cflat.ast.ParamSlots;
import net.loveruby.cflat.ast.Location;
import java.util.*;
public class ParamTypes extends ParamSlots<Type> {
protected ParamTypes(Location loc, List<Type> paramDescs, boolean vararg) {
super(loc, paramDescs, vararg);
}
public List<Type> types() {
return paramDescriptors;
}
public boolean isSameType(ParamTypes other) {
if (vararg != other.vararg) return false;
if (minArgc() != other.minArgc()) return false;
Iterator<Type> otherTypes = other.types().iterator();
for (Type t : paramDescriptors) {
if (! t.isSameType(otherTypes.next())) {
return false;
}
}
return true;
}
public boolean equals(Object other) {
return (other instanceof ParamTypes) && equals((ParamTypes)other);
}
public boolean equals(ParamTypes other) {
return vararg == other.vararg
&& paramDescriptors.equals(other.paramDescriptors);
}
}

View File

@ -5,7 +5,7 @@ import net.loveruby.cflat.asm.Assembler;
import java.util.*;
public class StructType extends CompositeType {
public StructType(String name, List membs, Location loc) {
public StructType(String name, List<Slot> membs, Location loc) {
super(name, membs, loc);
}
@ -19,9 +19,7 @@ public class StructType extends CompositeType {
protected void computeOffsets() {
long offset = 0;
long maxAlign = 1;
Iterator membs = members();
while (membs.hasNext()) {
Slot s = (Slot)membs.next();
for (Slot s : members()) {
offset = Assembler.align(offset, s.allocSize());
s.setOffset(offset);
offset += s.allocSize();

View File

@ -34,11 +34,11 @@ public class TypeTable {
}
protected int pointerSize;
protected Map table;
protected Map<TypeRef, Type> table;
public TypeTable(int ptrsize) {
pointerSize = ptrsize;
table = new HashMap();
table = new HashMap<TypeRef, Type>();
}
public boolean isDefined(TypeRef ref) {
@ -53,7 +53,7 @@ public class TypeTable {
}
public Type get(TypeRef ref) {
Type type = (Type)table.get(ref);
Type type = table.get(ref);
if (type == null) {
if (ref instanceof UserTypeRef) {
// If unregistered UserType is used in program, it causes
@ -104,8 +104,8 @@ public class TypeTable {
throw new Error("must not happen: integer.size != pointer.size");
}
public Iterator types() {
return table.values().iterator();
public Collection<Type> types() {
return table.values();
}
public VoidType voidType() {
@ -149,12 +149,10 @@ public class TypeTable {
}
public void semanticCheck(ErrorHandler h) {
Iterator types = table.values().iterator();
while (types.hasNext()) {
// We can safely use instanceof instead of isXXXX() here,
for (Type t : types()) {
// We can safely use "instanceof" instead of isXXXX() here,
// because the type refered from UserType must be also
// kept in this table.
Type t = (Type)types.next();
if (t instanceof CompositeType) {
checkVoidMembers((CompositeType)t, h);
checkDuplicatedMembers((CompositeType)t, h);
@ -173,38 +171,34 @@ public class TypeTable {
}
protected void checkVoidMembers(CompositeType t, ErrorHandler h) {
Iterator membs = t.members();
while (membs.hasNext()) {
Slot memb = (Slot)membs.next();
if (memb.type().isVoid()) {
for (Slot s : t.members()) {
if (s.type().isVoid()) {
h.error(t.location(), "struct/union cannot contain void");
}
}
}
protected void checkDuplicatedMembers(CompositeType t, ErrorHandler h) {
Map seen = new HashMap();
Iterator membs = t.members();
while (membs.hasNext()) {
Slot memb = (Slot)membs.next();
if (seen.containsKey(memb.name())) {
Map<String, Slot> seen = new HashMap<String, Slot>();
for (Slot s : t.members()) {
if (seen.containsKey(s.name())) {
h.error(t.location(),
t.toString() + " has duplicated member: "
+ memb.name());
t.toString() + " has duplicated member: " + s.name());
}
seen.put(memb.name(), memb);
seen.put(s.name(), s);
}
}
// #@@range/checkRecursiveDefinition{
protected void checkRecursiveDefinition(Type t, ErrorHandler h) {
_checkRecursiveDefinition(t, new HashMap(), h);
_checkRecursiveDefinition(t, new HashMap<Type, Object>(), h);
}
static final protected Object checking = new Object();
static final protected Object checked = new Object();
protected void _checkRecursiveDefinition(Type t, Map marks,
protected void _checkRecursiveDefinition(Type t,
Map<Type, Object> marks,
ErrorHandler h) {
if (marks.get(t) == checking) {
h.error(((NamedType)t).location(),
@ -218,10 +212,8 @@ public class TypeTable {
marks.put(t, checking);
if (t instanceof CompositeType) {
CompositeType ct = (CompositeType)t;
Iterator membs = ct.members();
while (membs.hasNext()) {
Slot slot = (Slot)membs.next();
_checkRecursiveDefinition(slot.type(), marks, h);
for (Slot s : ct.members()) {
_checkRecursiveDefinition(s.type(), marks, h);
}
}
else if (t instanceof ArrayType) {

View File

@ -5,7 +5,7 @@ import net.loveruby.cflat.asm.Assembler;
import java.util.*;
public class UnionType extends CompositeType {
public UnionType(String name, List membs, Location loc) {
public UnionType(String name, List<Slot> membs, Location loc) {
super(name, membs, loc);
}
@ -19,9 +19,7 @@ public class UnionType extends CompositeType {
protected void computeOffsets() {
long maxSize = 0;
long maxAlign = 1;
Iterator membs = members.iterator();
while (membs.hasNext()) {
Slot s = (Slot)membs.next();
for (Slot s : members) {
s.setOffset(0);
maxSize = Math.max(maxSize, s.allocSize());
maxAlign = Math.max(maxAlign, s.alignment());

View File

@ -1,36 +1,32 @@
package net.loveruby.cflat.utils;
import java.util.*;
public class Cursor implements Iterator {
protected List list;
public class Cursor<T> implements Iterator {
protected List<T> list;
protected int index;
public Cursor(List list) {
public Cursor(List<T> list) {
this(list, 0);
}
protected Cursor(List list, int index) {
protected Cursor(List<T> list, int index) {
this.list = list;
this.index = index;
}
public Object clone() {
return new Cursor(list, index);
}
public Cursor dup() {
return new Cursor(list, index);
public Cursor<T> clone() {
return new Cursor<T>(list, index);
}
public boolean hasNext() {
return index < list.size();
}
public Object next() {
public T next() {
return list.get(index++);
}
public Object current() {
public T current() {
if (index == 0) {
throw new Error("must not happen: Cursor#current");
}