* net/loveruby/cflat/ast/Node.java: all nodes must contain Location.

* net/loveruby/cflat/ast/*Node.java: ditto.
* net/loveruby/cflat/ast/Location.java: new class.
* net/loveruby/cflat/ast/Dumper.java (printClass): show location.
* net/loveruby/cflat/type/*Ref.java: support Location.
* net/loveruby/cflat/parser/Parser.jj: pass location to nodes.
* net/loveruby/cflat/parser/Parser.jj: long long removed.
* net/loveruby/cflat/type/SignedLongLongRef.java: ditto.
* net/loveruby/cflat/type/UnsignedLongLongRef.java: ditto.
* net/loveruby/cflat/type/SignedLongLongType.java: ditto.
* net/loveruby/cflat/type/UnsignedLongLongType.java: ditto.
* net/loveruby/cflat/type/TypeTable.java: ditto.
* net/loveruby/cflat/ast/LiteralNode.java: introduce new superclass of all literal nodes.
* net/loveruby/cflat/ast/StmtNode.java: introduce new superclass of all statement nodes.
* net/loveruby/cflat/ast/Declaration.java: is subclass of Node.
* net/loveruby/cflat/ast/Dumpable.java: removed: Now declarations are subclass of Node.
* net/loveruby/cflat/ast/Dumper.java: follow new class hierarchy.
* net/loveruby/cflat/ast/DefinitionVisitor.java: removed: merge into ASTVisitor again.
* net/loveruby/cflat/compiler/Visitor.java: follow new class hierarchy.
* net/loveruby/cflat/compiler/CodeGenerator.java: ditto.
* net/loveruby/cflat/compiler/TypeResolver.java: ditto.


git-svn-id: file:///Users/aamine/c/gitwork/public/cbc/trunk@3800 1b9489fe-b721-0410-924e-b54b9192deb8
This commit is contained in:
Minero Aoki 2008-01-05 01:34:27 +00:00
parent 57b38c5a86
commit 879738ba62
78 changed files with 530 additions and 305 deletions

View File

@ -1,3 +1,53 @@
Sat Jan 5 10:34:24 2008 Minero Aoki <aamine@loveruby.net>
* net/loveruby/cflat/ast/Node.java: all nodes must contain
Location.
* net/loveruby/cflat/ast/*Node.java: ditto.
* net/loveruby/cflat/ast/Location.java: new class.
* net/loveruby/cflat/ast/Dumper.java (printClass): show location.
* net/loveruby/cflat/type/*Ref.java: support Location.
* net/loveruby/cflat/parser/Parser.jj: pass location to nodes.
* net/loveruby/cflat/parser/Parser.jj: long long removed.
* net/loveruby/cflat/type/SignedLongLongRef.java: ditto.
* net/loveruby/cflat/type/UnsignedLongLongRef.java: ditto.
* net/loveruby/cflat/type/SignedLongLongType.java: ditto.
* net/loveruby/cflat/type/UnsignedLongLongType.java: ditto.
* net/loveruby/cflat/type/TypeTable.java: ditto.
* net/loveruby/cflat/ast/LiteralNode.java: introduce new
superclass of all literal nodes.
* net/loveruby/cflat/ast/StmtNode.java: introduce new superclass
of all statement nodes.
* net/loveruby/cflat/ast/Declaration.java: is subclass of Node.
* net/loveruby/cflat/ast/Dumpable.java: removed: Now declarations
are subclass of Node.
* net/loveruby/cflat/ast/Dumper.java: follow new class hierarchy.
* net/loveruby/cflat/ast/DefinitionVisitor.java: removed: merge
into ASTVisitor again.
* net/loveruby/cflat/compiler/Visitor.java: follow new class
hierarchy.
* net/loveruby/cflat/compiler/CodeGenerator.java: ditto.
* net/loveruby/cflat/compiler/TypeResolver.java: ditto.
Sat Jan 5 08:00:26 2008 Minero Aoki <aamine@loveruby.net>
* test/test.sh: compile command by myself before run it.

View File

@ -82,6 +82,10 @@ public class AST extends Node {
return constantTable;
}
public Location location() {
return new Location(fileName, 0, 0);
}
protected void _dump(Dumper d) {
d.printNodeList("variables", variables());
d.printNodeList("functions", functions());

View File

@ -62,4 +62,12 @@ public interface ASTVisitor {
public void visit(PrefixIncNode node);
public void visit(PrefixDecNode node);
public void visit(CastNode node);
public void visit(DefinedVariable var);
public void visit(UndefinedVariable var);
public void visit(DefinedFunction func);
public void visit(UndefinedFunction func);
public void visit(StructNode struct);
public void visit(UnionNode union);
public void visit(TypedefNode typedef);
}

View File

@ -26,6 +26,10 @@ abstract public class AbstractAssignNode extends ExprNode {
this.rhs = node;
}
public Location location() {
return lhs.location();
}
protected void _dump(Dumper d) {
d.printMember("lhs", lhs);
d.printMember("rhs", rhs);

View File

@ -36,6 +36,10 @@ public class ArefNode extends ExprNode implements LHSNode {
throw new Error("ArefNode#address");
}
public Location location() {
return expr.location();
}
protected void _dump(Dumper d) {
d.printMember("expr", expr);
d.printMember("index", index);

View File

@ -37,6 +37,10 @@ abstract public class BinaryOpNode extends ExprNode {
this.right = right;
}
public Location location() {
return left.location();
}
protected void _dump(Dumper d) {
d.printMember("left", left);
d.printMember("right", right);

View File

@ -1,11 +1,12 @@
package net.loveruby.cflat.ast;
import java.util.*;
public class BlockNode extends Node {
public class BlockNode extends StmtNode {
protected List variables;
protected List stmts;
public BlockNode(List vars, List ss) {
public BlockNode(Location loc, List vars, List ss) {
super(loc);
variables = vars;
stmts = ss;
}

View File

@ -1,9 +1,9 @@
package net.loveruby.cflat.ast;
import net.loveruby.cflat.asm.*;
public class BreakNode extends Node {
public BreakNode() {
super();
public class BreakNode extends StmtNode {
public BreakNode(Location loc) {
super(loc);
}
protected Label label;
@ -19,6 +19,10 @@ public class BreakNode extends Node {
return label;
}
public Location location() {
return location;
}
protected void _dump(Dumper d) {
}

View File

@ -31,6 +31,10 @@ public class CaseNode extends Node {
return beginLabel;
}
public Location location() {
return ((Node)values.get(0)).location();
}
protected void _dump(Dumper d) {
d.printNodeList("values", values);
d.printMember("body", body);

View File

@ -30,6 +30,10 @@ public class CastNode extends ExprNode {
return expr.isAssignable();
}
public Location location() {
return typeNode.location();
}
protected void _dump(Dumper d) {
d.printMember("typeNode", typeNode);
d.printMember("expr", expr);

View File

@ -1,21 +1,12 @@
package net.loveruby.cflat.ast;
import net.loveruby.cflat.type.*;
public class CharacterLiteralNode extends ExprNode {
protected TypeNode typeNode;
public class CharacterLiteralNode extends LiteralNode {
protected long value;
public CharacterLiteralNode(TypeRef ref, long i) {
typeNode = new TypeNode(ref);
value = i;
}
public Type type() {
return typeNode.type();
}
public TypeNode typeNode() {
return typeNode;
public CharacterLiteralNode(Location loc, TypeRef ref, long value) {
super(loc, ref);
value = value;
}
public long value() {

View File

@ -4,32 +4,23 @@ import java.util.*;
abstract public class ComplexTypeDefinition extends TypeDefinition {
protected List members; // List<Slot>
protected TypeNode typeNode;
public ComplexTypeDefinition(TypeRef ref, String name, List membs) {
super(name);
public ComplexTypeDefinition(Location loc,
TypeRef ref, String name, List membs) {
super(loc, ref, name);
members = membs;
typeNode = new TypeNode(ref);
}
public boolean isComplexType() {
return true;
}
abstract public String type();
abstract public String kind();
public List members() {
return members;
}
public TypeRef typeRef() {
return typeNode.typeRef();
}
public TypeNode typeNode() {
return typeNode;
}
protected void _dump(Dumper d) {
d.printMember("name", name);
d.printNodeList("members", members);

View File

@ -54,6 +54,10 @@ public class CondExprNode extends ExprNode {
return endLabel;
}
public Location location() {
return cond.location();
}
protected void _dump(Dumper d) {
d.printMember("cond", cond);
d.printMember("thenExpr", thenExpr);

View File

@ -1,9 +1,9 @@
package net.loveruby.cflat.ast;
import net.loveruby.cflat.asm.*;
public class ContinueNode extends Node {
public ContinueNode() {
super();
public class ContinueNode extends StmtNode {
public ContinueNode(Location loc) {
super(loc);
}
protected Label label;

View File

@ -1,6 +1,6 @@
package net.loveruby.cflat.ast;
abstract public class Declaration implements Dumpable {
abstract public class Declaration extends Node {
protected String name;
public Declaration(String n) {
@ -10,13 +10,4 @@ abstract public class Declaration implements Dumpable {
public String name() {
return name;
}
public void dump(Dumper d) {
d.printClass(this);
_dump(d);
}
abstract void _dump(Dumper d);
abstract public void accept(DefinitionVisitor visitor);
}

View File

@ -115,7 +115,7 @@ public class DefinedFunction extends Function {
d.printMember("body", body);
}
public void accept(DefinitionVisitor visitor) {
public void accept(ASTVisitor visitor) {
visitor.visit(this);
}
}

View File

@ -49,7 +49,7 @@ public class DefinedVariable extends Variable {
d.printMember("initializer", initializer);
}
public void accept(DefinitionVisitor visitor) {
public void accept(ASTVisitor visitor) {
visitor.visit(this);
}
}

View File

@ -1,11 +0,0 @@
package net.loveruby.cflat.ast;
public interface DefinitionVisitor {
public void visit(DefinedVariable var);
public void visit(UndefinedVariable var);
public void visit(DefinedFunction func);
public void visit(UndefinedFunction func);
public void visit(StructNode struct);
public void visit(UnionNode union);
public void visit(TypedefNode typedef);
}

View File

@ -5,8 +5,9 @@ public class DoWhileNode extends LoopNode {
protected ExprNode cond;
protected Node body;
public DoWhileNode(LabelPool pool, Node body, ExprNode cond) {
super(pool);
public DoWhileNode(Location loc, LabelPool pool,
Node body, ExprNode cond) {
super(loc, pool);
this.body = body;
this.cond = cond;
}

View File

@ -1,5 +0,0 @@
package net.loveruby.cflat.ast;
public interface Dumpable {
void dump(Dumper d);
}

View File

@ -13,14 +13,14 @@ public class Dumper {
this.nIndent = 0;
}
public void printClass(Object obj) {
public void printClass(Object obj, Location loc) {
printIndent();
stream.println(className(obj));
stream.println("<<" + className(obj) + ">> (" + loc + ")");
}
protected String className(Object obj) {
String[] ids = obj.getClass().getName().split("\\.");
return "<<" + ids[ids.length - 1] + ">>";
return ids[ids.length - 1];
}
public void printNodeList(String name, List list) {
@ -32,8 +32,8 @@ public class Dumper {
stream.println(name + ":");
indent();
while (list.hasNext()) {
Dumpable i = (Dumpable)list.next();
i.dump(this);
Node n = (Node)list.next();
n.dump(this);
}
unindent();
}

View File

@ -50,4 +50,8 @@ abstract public class Entity extends Definition {
abstract public void defineIn(ToplevelScope toplevel);
abstract public AsmEntity address();
public Location location() {
return typeNode.location();
}
}

View File

@ -3,10 +3,21 @@ import net.loveruby.cflat.type.*;
import java.util.*;
public class FixedParams extends Params {
protected Location location;
protected List parameters;
public FixedParams(List params) {
parameters = params;
this(null, params);
}
public FixedParams(Location loc, List params) {
super();
this.location = loc;
this.parameters = params;
}
public Location location() {
return location;
}
/**
@ -51,7 +62,7 @@ public class FixedParams extends Params {
while (it.hasNext()) {
types.add(table.get((TypeRef)it.next()));
}
return new FixedParams(types);
return new FixedParams(location, types);
}
public Params typeRefs() {
@ -61,6 +72,6 @@ public class FixedParams extends Params {
Parameter param = (Parameter)it.next();
typerefs.add(param.typeNode().typeRef());
}
return new FixedParams(typerefs);
return new FixedParams(location, typerefs);
}
}

View File

@ -5,9 +5,9 @@ public class ForNode extends LoopNode {
protected ExprNode init, cond, incr;
protected Node body;
public ForNode(LabelPool pool,
public ForNode(Location loc, LabelPool pool,
ExprNode init, ExprNode cond, ExprNode incr, Node body) {
super(pool);
super(loc, pool);
this.init = init;
this.cond = cond;
this.incr = incr;

View File

@ -68,6 +68,10 @@ public class FuncallNode extends ExprNode {
return arguments.listIterator(arguments.size());
}
public Location location() {
return expr.location();
}
protected void _dump(Dumper d) {
d.printMember("expr", expr);
d.printNodeList("arguments", arguments);

View File

@ -1,12 +1,12 @@
package net.loveruby.cflat.ast;
import net.loveruby.cflat.asm.Label;
public class GotoNode extends Node {
public class GotoNode extends StmtNode {
protected String target;
protected Label label;
public GotoNode(String target) {
super();
public GotoNode(Location loc, String target) {
super(loc);
this.target = target;
}

View File

@ -1,14 +1,14 @@
package net.loveruby.cflat.ast;
import net.loveruby.cflat.asm.*;
public class IfNode extends Node {
public class IfNode extends StmtNode {
protected ExprNode cond;
protected Node thenBody, elseBody;
protected LabelPool pool;
protected Label elseLabel, endLabel;
public IfNode(LabelPool lp, ExprNode c, Node t, Node e) {
super();
public IfNode(Location loc, LabelPool lp, ExprNode c, Node t, Node e) {
super(loc);
pool = lp;
cond = c;
thenBody = t;

View File

@ -1,21 +1,12 @@
package net.loveruby.cflat.ast;
import net.loveruby.cflat.type.*;
public class IntegerLiteralNode extends ExprNode {
protected TypeNode typeNode;
public class IntegerLiteralNode extends LiteralNode {
protected long value;
public IntegerLiteralNode(TypeRef ref, long i) {
typeNode = new TypeNode(ref);
value = i;
}
public Type type() {
return typeNode.type();
}
public TypeNode typeNode() {
return typeNode;
public IntegerLiteralNode(Location loc, TypeRef ref, long value) {
super(loc, ref);
this.value = value;
}
public long value() {

View File

@ -1,13 +1,13 @@
package net.loveruby.cflat.ast;
import net.loveruby.cflat.asm.Label;
public class LabelNode extends Node {
public class LabelNode extends StmtNode {
protected String name;
protected Node stmt;
protected Label label;
public LabelNode(String name, Node stmt) {
super();
public LabelNode(Location loc, String name, Node stmt) {
super(loc);
this.name = name;
this.stmt = stmt;
}

View File

@ -0,0 +1,25 @@
package net.loveruby.cflat.ast;
import net.loveruby.cflat.type.*;
abstract public class LiteralNode extends ExprNode {
protected Location location;
protected TypeNode typeNode;
public LiteralNode(Location loc, TypeRef ref) {
super();
this.location = loc;
this.typeNode = new TypeNode(ref);
}
public Location location() {
return location;
}
public Type type() {
return typeNode.type();
}
public TypeNode typeNode() {
return typeNode;
}
}

View File

@ -0,0 +1,25 @@
package net.loveruby.cflat.ast;
public class Location {
protected String source;
protected int line;
protected int column;
public Location(String source, int line, int column) {
this.source = source;
this.line = line;
this.column = column;
}
public String source() {
return source;
}
public int line() {
return line;
}
public String toString() {
return source + ":" + line;
}
}

View File

@ -1,13 +1,13 @@
package net.loveruby.cflat.ast;
import net.loveruby.cflat.asm.*;
abstract public class LoopNode extends Node
abstract public class LoopNode extends StmtNode
implements BreakableStmt, ContinueableStmt {
protected LabelPool pool;
protected Label begLabel, endLabel;
public LoopNode(LabelPool lp) {
super();
public LoopNode(Location loc, LabelPool lp) {
super(loc);
pool = lp;
}

View File

@ -51,6 +51,10 @@ public class MemberNode extends ExprNode implements LHSNode {
return ((LHSNode)expr).address().add(offset());
}
public Location location() {
return expr.location();
}
protected void _dump(Dumper d) {
d.printMember("expr", expr);
d.printMember("name", name);

View File

@ -1,10 +1,12 @@
package net.loveruby.cflat.ast;
import java.io.*;
abstract public class Node implements Dumpable {
abstract public class Node {
public Node() {
}
abstract public Location location();
public void dump() {
dump(System.out);
}
@ -14,11 +16,11 @@ abstract public class Node implements Dumpable {
}
public void dump(Dumper d) {
d.printClass(this);
d.printClass(this, location());
_dump(d);
}
abstract void _dump(Dumper d);
abstract protected void _dump(Dumper d);
abstract public void accept(ASTVisitor visitor);
}

View File

@ -3,8 +3,8 @@ import net.loveruby.cflat.type.TypeTable;
import java.util.*;
abstract public class Params extends Node {
public void accept(ASTVisitor visitor) {
throw new Error("do not use Params#accept");
public Params() {
super();
}
abstract public Iterator parameters();
@ -18,4 +18,8 @@ abstract public class Params extends Node {
protected void _dump(Dumper d) {
d.printNodeList("parameters", parameters());
}
public void accept(ASTVisitor visitor) {
throw new Error("do not use Params#accept");
}
}

View File

@ -52,6 +52,10 @@ public class PtrMemberNode extends ExprNode implements LHSNode {
return dereferedType().memberOffset(name);
}
public Location location() {
return expr.location();
}
protected void _dump(Dumper d) {
d.printMember("expr", expr);
d.printMember("name", name);

View File

@ -1,11 +1,11 @@
package net.loveruby.cflat.ast;
public class ReturnNode extends Node {
ExprNode expr;
Function function;
public class ReturnNode extends StmtNode {
protected ExprNode expr;
protected Function function;
public ReturnNode(ExprNode expr) {
super();
public ReturnNode(Location loc, ExprNode expr) {
super(loc);
this.expr = expr;
}

View File

@ -1,7 +1,7 @@
package net.loveruby.cflat.ast;
import net.loveruby.cflat.type.*;
public class Slot implements Dumpable {
public class Slot extends Node {
protected TypeNode typeNode;
protected String name;
protected long offset;
@ -40,9 +40,16 @@ public class Slot implements Dumpable {
this.offset = offset;
}
public void dump(Dumper d) {
d.printClass(this);
public Location location() {
return typeNode.location();
}
protected void _dump(Dumper d) {
d.printMember("name", name);
d.printMember("typeNode", typeNode);
}
public void accept(ASTVisitor visitor) {
throw new Error("Slot#accept");
}
}

View File

@ -0,0 +1,13 @@
package net.loveruby.cflat.ast;
abstract public class StmtNode extends Node {
protected Location location;
public StmtNode(Location loc) {
this.location = loc;
}
public Location location() {
return location;
}
}

View File

@ -2,22 +2,13 @@ package net.loveruby.cflat.ast;
import net.loveruby.cflat.type.*;
import net.loveruby.cflat.asm.*;
public class StringLiteralNode extends ExprNode {
protected TypeNode typeNode;
public class StringLiteralNode extends LiteralNode {
protected String value;
protected ConstantEntry entry;
public StringLiteralNode(TypeRef ref, String s) {
typeNode = new TypeNode(ref);
value = s;
}
public TypeNode typeNode() {
return typeNode;
}
public Type type() {
return typeNode.type();
public StringLiteralNode(Location loc, TypeRef ref, String value) {
super(loc, ref);
this.value = value;
}
public String value() {

View File

@ -3,18 +3,14 @@ import net.loveruby.cflat.type.*;
import java.util.*;
public class StructNode extends ComplexTypeDefinition {
public StructNode(TypeRef ref, String name, List membs) {
super(ref, name, membs);
public StructNode(Location loc, TypeRef ref, String name, List membs) {
super(loc, ref, name, membs);
}
public String type() {
public String kind() {
return "struct";
}
public TypeRef typeRef() {
return super.typeRef();
}
public boolean isStruct() {
return true;
}
@ -23,7 +19,7 @@ public class StructNode extends ComplexTypeDefinition {
table.defineStruct((StructTypeRef)typeRef(), members());
}
public void accept(DefinitionVisitor visitor) {
public void accept(ASTVisitor visitor) {
visitor.visit(this);
}
}

View File

@ -2,14 +2,15 @@ package net.loveruby.cflat.ast;
import net.loveruby.cflat.asm.*;
import java.util.*;
public class SwitchNode extends Node implements BreakableStmt {
public class SwitchNode extends StmtNode implements BreakableStmt {
protected LabelPool pool;
protected ExprNode cond;
protected List cases;
protected Label endLabel;
public SwitchNode(LabelPool pool, ExprNode cond, List cases) {
super();
public SwitchNode(Location loc, LabelPool pool,
ExprNode cond, List cases) {
super(loc);
this.pool = pool;
this.cond = cond;
this.cases = cases;

View File

@ -2,15 +2,34 @@ package net.loveruby.cflat.ast;
import net.loveruby.cflat.type.*;
abstract public class TypeDefinition extends Definition {
public TypeDefinition(String name) {
protected Location location;
protected TypeNode typeNode;
public TypeDefinition(Location loc, TypeRef ref, String name) {
super(name);
this.location = loc;
this.typeNode = new TypeNode(ref);
}
public Location location() {
return location;
}
public boolean isType() {
return true;
}
abstract public TypeNode typeNode();
abstract public TypeRef typeRef();
public TypeNode typeNode() {
return typeNode;
}
public TypeRef typeRef() {
return typeNode.typeRef();
}
public Type type() {
return typeNode.type();
}
abstract public void defineIn(TypeTable table);
}

View File

@ -37,6 +37,10 @@ public class TypeNode extends Node {
return type;
}
public Location location() {
return typeRef.location();
}
protected void _dump(Dumper d) {
d.printMember("typeref", typeRef);
d.printMember("type", type);

View File

@ -2,29 +2,14 @@ package net.loveruby.cflat.ast;
import net.loveruby.cflat.type.*;
public class TypedefNode extends TypeDefinition {
protected TypeNode typeNode;
public TypedefNode(TypeNode t, String name) {
super(name);
typeNode = t;
public TypedefNode(Location loc, TypeRef ref, String name) {
super(loc, ref, name);
}
public boolean isUserType() {
return true;
}
public TypeRef typeRef() {
return typeNode.typeRef();
}
public TypeNode typeNode() {
return typeNode;
}
public Type type() {
return typeNode.type();
}
public void defineIn(TypeTable table) {
table.defineUserType(new UserTypeRef(name()), typeNode());
}
@ -34,7 +19,7 @@ public class TypedefNode extends TypeDefinition {
d.printMember("typeNode", typeNode);
}
public void accept(DefinitionVisitor visitor) {
public void accept(ASTVisitor visitor) {
visitor.visit(this);
}
}

View File

@ -16,6 +16,10 @@ abstract public class UnaryOpNode extends ExprNode {
return expr;
}
public Location location() {
return expr.location();
}
protected void _dump(Dumper d) {
d.printMember("expr", expr);
}

View File

@ -34,7 +34,7 @@ public class UndefinedFunction extends Function {
d.printMember("params", params);
}
public void accept(DefinitionVisitor visitor) {
public void accept(ASTVisitor visitor) {
visitor.visit(this);
}
}

View File

@ -25,7 +25,7 @@ public class UndefinedVariable extends Variable {
d.printMember("typeNode", typeNode);
}
public void accept(DefinitionVisitor visitor) {
public void accept(ASTVisitor visitor) {
visitor.visit(this);
}
}

View File

@ -3,18 +3,14 @@ import net.loveruby.cflat.type.*;
import java.util.*;
public class UnionNode extends ComplexTypeDefinition {
public UnionNode(TypeRef ref, String name, List membs) {
super(ref, name, membs);
public UnionNode(Location loc, TypeRef ref, String name, List membs) {
super(loc, ref, name, membs);
}
public String type() {
public String kind() {
return "union";
}
public TypeRef typeRef() {
return (UnionTypeRef)super.typeRef();
}
public boolean isUnion() {
return true;
}
@ -23,7 +19,7 @@ public class UnionNode extends ComplexTypeDefinition {
table.defineUnion((UnionTypeRef)typeRef(), members());
}
public void accept(DefinitionVisitor visitor) {
public void accept(ASTVisitor visitor) {
visitor.visit(this);
}
}

View File

@ -6,6 +6,7 @@ public class VarParams extends Params {
protected FixedParams params;
public VarParams(FixedParams params) {
super();
this.params = params;
}
@ -42,4 +43,8 @@ public class VarParams extends Params {
public Params typeRefs() {
return new VarParams((FixedParams)params.typeRefs());
}
public Location location() {
return params.location();
}
}

View File

@ -3,12 +3,14 @@ import net.loveruby.cflat.type.Type;
import net.loveruby.cflat.asm.*;
public class VariableNode extends ExprNode implements LHSNode {
protected Location location;
protected String name;
protected Entity entity;
public VariableNode(String n) {
public VariableNode(Location loc, String name) {
super();
name = n;
this.location = loc;
this.name = name;
}
public String name() {
@ -48,6 +50,10 @@ public class VariableNode extends ExprNode implements LHSNode {
return entity.address();
}
public Location location() {
return location;
}
protected void _dump(Dumper d) {
d.printMember("name", name);
}

View File

@ -5,8 +5,9 @@ public class WhileNode extends LoopNode {
protected ExprNode cond;
protected Node body;
public WhileNode(LabelPool pool, ExprNode cond, Node body) {
super(pool);
public WhileNode(Location loc, LabelPool pool,
ExprNode cond, Node body) {
super(loc, pool);
this.cond = cond;
this.body = body;
}

View File

@ -4,7 +4,7 @@ import net.loveruby.cflat.type.*;
import net.loveruby.cflat.asm.*;
import java.util.*;
public class CodeGenerator implements ASTVisitor {
public class CodeGenerator extends Visitor {
static public String generate(AST ast, TypeTable typeTable,
ErrorHandler errorHandler) {
CodeGenerator gen = new CodeGenerator(new Assembler(), errorHandler);

View File

@ -3,7 +3,7 @@ import net.loveruby.cflat.ast.*;
import net.loveruby.cflat.type.*;
import java.util.*;
public class TypeResolver extends Visitor implements DefinitionVisitor {
public class TypeResolver extends Visitor {
static public void resolve(AST ast, TypeTable typeTable,
ErrorHandler errorHandler) {
new TypeResolver(typeTable, errorHandler).resolveProgram(ast);

View File

@ -281,4 +281,16 @@ public class Visitor implements ASTVisitor {
public void visit(CastNode node) {
resolve(node.expr());
}
//
// Declarations
//
public void visit(DefinedVariable var) {}
public void visit(UndefinedVariable var) {}
public void visit(DefinedFunction func) {}
public void visit(UndefinedFunction func) {}
public void visit(StructNode struct) {}
public void visit(UnionNode union) {}
public void visit(TypedefNode typedef) {}
}

View File

@ -99,16 +99,16 @@ public class Parser {
return knownTypedefs.contains(name);
}
private IntegerLiteralNode integerNodeValue(String image) {
private IntegerLiteralNode integerNodeValue(Location loc, String image) {
long i = integerValue(image);
if (image.endsWith("UL")) {
return new IntegerLiteralNode(new UnsignedLongRef(), i);
return new IntegerLiteralNode(loc, new UnsignedLongRef(), i);
} else if (image.endsWith("L")) {
return new IntegerLiteralNode(new SignedLongRef(), i);
return new IntegerLiteralNode(loc, new SignedLongRef(), i);
} else if (image.endsWith("U")) {
return new IntegerLiteralNode(new UnsignedIntRef(), i);
return new IntegerLiteralNode(loc, new UnsignedIntRef(), i);
} else {
return new IntegerLiteralNode(new SignedIntRef(), i);
return new IntegerLiteralNode(loc, new SignedIntRef(), i);
}
}
@ -192,6 +192,10 @@ public class Parser {
throw new ParseException("unknown escape sequence: \"\\" + c);
}
}
protected Location loc(Token t) {
return new Location(sourceName, t.beginLine, t.beginColumn);
}
}
PARSER_END(Parser)
@ -438,12 +442,15 @@ boolean storage():
}
Params params():
{ FixedParams params; }
{
Token t;
FixedParams params;
}
{
LOOKAHEAD(<VOID> ")")
<VOID>
t=<VOID>
{
return new FixedParams(new ArrayList());
return new FixedParams(loc(t), new ArrayList());
}
| params=fixedparams()
["," "..." { return new VarParams(params); }]
@ -455,13 +462,13 @@ Params params():
FixedParams fixedparams():
{
List params = new ArrayList();
Parameter param;
Parameter param, param1;
}
{
param=param() { params.add(param); }
param1=param() { params.add(param1); }
( LOOKAHEAD(2) "," param=param() { params.add(param); } )*
{
return new FixedParams(params);
return new FixedParams(param1.location(), params);
}
}
@ -476,38 +483,41 @@ Parameter param():
BlockNode block():
{
Token t;
List list = new ArrayList();
List vars;
List stmts;
}
{
"{" (vars=defvars() { list.addAll(vars); })* stmts=stmts() "}"
t="{" (vars=defvars() { list.addAll(vars); })* stmts=stmts() "}"
{
return new BlockNode(list, stmts);
return new BlockNode(loc(t), list, stmts);
}
}
StructNode defstruct():
{
Token t;
String n;
List membs;
}
{
<STRUCT> n=name() membs=member_list() ";"
t=<STRUCT> n=name() membs=member_list() ";"
{
return new StructNode(new StructTypeRef(n), n, membs);
return new StructNode(loc(t), new StructTypeRef(n), n, membs);
}
}
UnionNode defunion():
{
Token t;
String n;
List membs;
}
{
<UNION> n=name() membs=member_list() ";"
t=<UNION> n=name() membs=member_list() ";"
{
return new UnionNode(new UnionTypeRef(n), n, membs);
return new UnionNode(loc(t), new UnionTypeRef(n), n, membs);
}
}
@ -626,39 +636,42 @@ FixedParams fixedparam_typerefs():
}
TypeRef typeref_base():
{ Token t; }
{
<VOID> { return new VoidTypeRef(); }
| <CHAR> { return new SignedCharRef(); }
| <SHORT> { return new SignedShortRef(); }
| <INT> { return new SignedIntRef(); }
| LOOKAHEAD(2) <LONG> <LONG> { return new SignedLongLongRef(); }
| <LONG> { return new SignedLongRef(); }
| LOOKAHEAD(2) <UNSIGNED> <CHAR> { return new UnsignedCharRef(); }
| LOOKAHEAD(2) <UNSIGNED> <SHORT> { return new UnsignedShortRef(); }
| LOOKAHEAD(2) <UNSIGNED> <INT> { return new UnsignedIntRef(); }
| LOOKAHEAD(3) <UNSIGNED> <LONG> <LONG>
{ return new UnsignedLongLongRef(); }
| LOOKAHEAD(2) <UNSIGNED> <LONG>
{ return new UnsignedLongRef(); }
| <STRUCT> t=<IDENTIFIER>
{ return new StructTypeRef(t.image); }
| <UNION> t=<IDENTIFIER>
{ return new UnionTypeRef(t.image); }
| LOOKAHEAD({isType(getToken(1).image)}) t=<IDENTIFIER>
{ return new UserTypeRef(t.image); }
Token t, name;
}
{
t=<VOID> { return new VoidTypeRef(loc(t)); }
| t=<CHAR> { return new SignedCharRef(loc(t)); }
| t=<SHORT> { return new SignedShortRef(loc(t)); }
| t=<INT> { return new SignedIntRef(loc(t)); }
| t=<LONG> { return new SignedLongRef(loc(t)); }
| LOOKAHEAD(2) t=<UNSIGNED> <CHAR>
{ return new UnsignedCharRef(loc(t)); }
| LOOKAHEAD(2) t=<UNSIGNED> <SHORT>
{ return new UnsignedShortRef(loc(t)); }
| LOOKAHEAD(2) t=<UNSIGNED> <INT>
{ return new UnsignedIntRef(loc(t)); }
| LOOKAHEAD(2) t=<UNSIGNED> <LONG>
{ return new UnsignedLongRef(loc(t)); }
| t=<STRUCT> name=<IDENTIFIER>
{ return new StructTypeRef(loc(t), name.image); }
| t=<UNION> name=<IDENTIFIER>
{ return new UnionTypeRef(loc(t), name.image); }
| LOOKAHEAD({isType(getToken(1).image)}) name=<IDENTIFIER>
{ return new UserTypeRef(loc(name), name.image); }
}
TypedefNode typedef():
{
TypeNode t;
Token t;
TypeRef ref;
Token newname;
}
{
<TYPEDEF> t=type() newname=<IDENTIFIER> ";"
t=<TYPEDEF> ref=typeref() newname=<IDENTIFIER> ";"
{
addType(newname.image);
return new TypedefNode(t, newname.image);
return new TypedefNode(loc(t), ref, newname.image);
}
}
@ -704,70 +717,75 @@ LabelNode labeled_stmt():
{
t=<IDENTIFIER> ":" n=stmt()
{
return new LabelNode(t.image, n);
return new LabelNode(loc(t), t.image, n);
}
}
IfNode if_stmt():
{
Token t;
ExprNode cond;
Node thenBody, elseBody = null;
}
{
<IF> "(" cond=expr() ")" thenBody=stmt()
t=<IF> "(" cond=expr() ")" thenBody=stmt()
[LOOKAHEAD(1) <ELSE> elseBody=stmt()]
{
return new IfNode(labelPool, cond, thenBody, elseBody);
return new IfNode(loc(t), labelPool, cond, thenBody, elseBody);
}
}
WhileNode while_stmt():
{
Token t;
ExprNode cond;
Node body;
}
{
<WHILE> "(" cond=expr() ")" body=stmt()
t=<WHILE> "(" cond=expr() ")" body=stmt()
{
return new WhileNode(labelPool, cond, body);
return new WhileNode(loc(t), labelPool, cond, body);
}
}
DoWhileNode dowhile_stmt():
{
Token t;
ExprNode cond;
Node body;
}
{
<DO> body=stmt() <WHILE> "(" cond=expr() ")" ";"
t=<DO> body=stmt() <WHILE> "(" cond=expr() ")" ";"
{
return new DoWhileNode(labelPool, body, cond);
return new DoWhileNode(loc(t), labelPool, body, cond);
}
}
ForNode for_stmt():
{
Token t;
ExprNode init = null, cond = null, incr = null;
Node body;
}
{
<FOR> "(" [init=expr()] ";"
t=<FOR> "(" [init=expr()] ";"
[cond=expr()] ";"
[incr=expr()] ")" body=stmt()
{
return new ForNode(labelPool, init, cond, incr, body);
return new ForNode(loc(t), labelPool, init, cond, incr, body);
}
}
SwitchNode switch_stmt():
{
Token t;
ExprNode cond;
List bodies;
}
{
<SWITCH> "(" cond=expr() ")" "{" bodies=case_clauses() "}"
t=<SWITCH> "(" cond=expr() ")" "{" bodies=case_clauses() "}"
{
return new SwitchNode(labelPool, cond, bodies);
return new SwitchNode(loc(t), labelPool, cond, bodies);
}
}
@ -830,31 +848,40 @@ BlockNode case_body():
throw new ParseException(
"missing break statement at the last of case clause");
}
return new BlockNode(new ArrayList(), ss);
return new BlockNode(((Node)ss.get(0)).location(),
new ArrayList(), ss);
}
}
GotoNode goto_stmt():
{ Token t, name; }
{
t=<GOTO> name=<IDENTIFIER> ";"
{
return new GotoNode(loc(t), name.image);
}
}
BreakNode break_stmt():
{ Token t; }
{
<GOTO> t=<IDENTIFIER> ";" { return new GotoNode(t.image); }
t=<BREAK> ";" { return new BreakNode(loc(t)); }
}
BreakNode break_stmt(): {}
ContinueNode continue_stmt():
{ Token t; }
{
<BREAK> ";" { return new BreakNode(); }
}
ContinueNode continue_stmt(): {}
{
<CONTINUE> ";" { return new ContinueNode(); }
t=<CONTINUE> ";" { return new ContinueNode(loc(t)); }
}
ReturnNode return_stmt():
{ ExprNode expr; }
{
LOOKAHEAD(2) <RETURN> ";" { return new ReturnNode(null); }
| <RETURN> expr=expr() ";" { return new ReturnNode(expr); }
Token t;
ExprNode expr;
}
{
LOOKAHEAD(2) t=<RETURN> ";" { return new ReturnNode(loc(t), null); }
| t=<RETURN> expr=expr() ";" { return new ReturnNode(loc(t), expr); }
}
ExprNode expr():
@ -1078,22 +1105,23 @@ ExprNode primary():
{
t=<INTEGER>
{
return integerNodeValue(t.image);
return integerNodeValue(loc(t), t.image);
}
| t=<CHARACTER>
{
return new CharacterLiteralNode(new SignedCharRef(),
return new CharacterLiteralNode(loc(t),
new SignedCharRef(null),
characterCode(t.image));
}
| t=<STRING>
{
return new StringLiteralNode(
return new StringLiteralNode(loc(t),
new PointerTypeRef(new SignedCharRef()),
stringValue(t.image));
}
| t=<IDENTIFIER>
{
return new VariableNode(t.image);
return new VariableNode(loc(t), t.image);
}
| "(" n=expr() ")"
{

View File

@ -6,11 +6,13 @@ public class ArrayTypeRef extends TypeRef {
static final protected long undefined = -1;
public ArrayTypeRef(TypeRef baseType) {
super(baseType.location());
this.baseType = baseType;
this.length = undefined;
}
public ArrayTypeRef(TypeRef baseType, long length) {
super(baseType.location());
if (length < 0) throw new Error("negative array length");
this.baseType = baseType;
this.length = length;

View File

@ -7,6 +7,7 @@ public class FunctionTypeRef extends TypeRef {
protected Params params;
public FunctionTypeRef(TypeRef returnType, Params params) {
super(returnType.location());
this.returnType = returnType;
this.params = params;
}

View File

@ -6,6 +6,7 @@ public class IntegerType extends Type {
protected String name;
public IntegerType(long sz, boolean sign, String nm) {
super();
size = sz;
signed = sign;
name = nm;

View File

@ -4,6 +4,7 @@ public class PointerTypeRef extends TypeRef {
protected TypeRef baseType;
public PointerTypeRef(TypeRef baseType) {
super(baseType.location());
this.baseType = baseType;
}

View File

@ -1,7 +1,13 @@
package net.loveruby.cflat.type;
import net.loveruby.cflat.ast.Location;
public class SignedCharRef extends TypeRef {
public SignedCharRef() {
super(null);
}
public SignedCharRef(Location loc) {
super(loc);
}
public boolean isSignedChar() {

View File

@ -1,7 +1,13 @@
package net.loveruby.cflat.type;
import net.loveruby.cflat.ast.Location;
public class SignedIntRef extends TypeRef {
public SignedIntRef() {
super(null);
}
public SignedIntRef(Location loc) {
super(loc);
}
public boolean isSignedInt() {

View File

@ -1,18 +0,0 @@
package net.loveruby.cflat.type;
public class SignedLongLongRef extends TypeRef {
public SignedLongLongRef() {
}
public boolean isSignedLongLong() {
return true;
}
public boolean equals(Object other) {
return (other instanceof SignedLongLongRef);
}
public int hashCode() {
return -2;
}
}

View File

@ -1,7 +0,0 @@
package net.loveruby.cflat.type;
public class SignedLongLongType extends IntegerType {
public SignedLongLongType(int size) {
super(size, true, "long_long");
}
}

View File

@ -1,7 +1,13 @@
package net.loveruby.cflat.type;
import net.loveruby.cflat.ast.Location;
public class SignedLongRef extends TypeRef {
public SignedLongRef() {
super(null);
}
public SignedLongRef(Location loc) {
super(loc);
}
public boolean isSignedLong() {

View File

@ -1,7 +1,13 @@
package net.loveruby.cflat.type;
import net.loveruby.cflat.ast.Location;
public class SignedShortRef extends TypeRef {
public SignedShortRef() {
super(null);
}
public SignedShortRef(Location loc) {
super(loc);
}
public boolean isSignedShort() {

View File

@ -1,10 +1,16 @@
package net.loveruby.cflat.type;
import net.loveruby.cflat.ast.Location;
public class StructTypeRef extends TypeRef {
protected String name;
public StructTypeRef(String n) {
name = n;
public StructTypeRef(String name) {
this(null, name);
}
public StructTypeRef(Location loc, String name) {
super(loc);
this.name = name;
}
public boolean isStruct() {

View File

@ -1,6 +1,17 @@
package net.loveruby.cflat.type;
import net.loveruby.cflat.ast.Location;
public abstract class TypeRef {
protected Location location;
public TypeRef(Location loc) {
this.location = loc;
}
public Location location() {
return location;
}
public boolean isVoid() { return false; }
public boolean isSignedChar() { return false; }
public boolean isSignedShort() { return false; }

View File

@ -5,37 +5,33 @@ import net.loveruby.cflat.exception.*;
import java.util.*;
public class TypeTable {
static public TypeTable ilp32() { return newTable(1, 2, 4, 4, 8, 4); }
static public TypeTable ilp64() { return newTable(1, 2, 8, 8, 8, 8); }
static public TypeTable lp64() { return newTable(1, 2, 4, 8, 8, 8); }
static public TypeTable llp64() { return newTable(1, 2, 4, 4, 8, 8); }
static public TypeTable ilp32() { return newTable(1, 2, 4, 4, 4); }
static public TypeTable ilp64() { return newTable(1, 2, 8, 8, 8); }
static public TypeTable lp64() { return newTable(1, 2, 4, 8, 8); }
static public TypeTable llp64() { return newTable(1, 2, 4, 4, 8); }
static protected final TypeRef voidTypeRef = new VoidTypeRef();
static protected final TypeRef signedCharRef = new SignedCharRef();
static protected final TypeRef signedShortRef = new SignedShortRef();
static protected final TypeRef signedIntRef = new SignedIntRef();
static protected final TypeRef signedLongRef = new SignedLongRef();
static protected final TypeRef signedLongLongRef = new SignedLongLongRef();
static protected final TypeRef unsignedCharRef = new UnsignedCharRef();
static protected final TypeRef unsignedShortRef = new UnsignedShortRef();
static protected final TypeRef unsignedIntRef = new UnsignedIntRef();
static protected final TypeRef unsignedLongRef = new UnsignedLongRef();
static protected final TypeRef unsignedLongLongRef = new UnsignedLongLongRef();
static private TypeTable newTable(int charsize, int shortsize,
int intsize, int longsize, int longlongsize, int ptrsize) {
int intsize, int longsize, int ptrsize) {
TypeTable table = new TypeTable(ptrsize);
table.put(voidTypeRef, new VoidType());
table.put(signedCharRef, new SignedCharType(charsize));
table.put(signedShortRef, new SignedShortType(shortsize));
table.put(signedIntRef, new SignedIntType(intsize));
table.put(signedLongRef, new SignedLongType(longsize));
table.put(signedLongLongRef, new SignedLongType(longlongsize));
table.put(unsignedCharRef, new UnsignedCharType(charsize));
table.put(unsignedShortRef, new UnsignedShortType(shortsize));
table.put(unsignedIntRef, new UnsignedIntType(intsize));
table.put(unsignedLongRef, new UnsignedLongType(longsize));
table.put(unsignedLongLongRef, new UnsignedLongLongType(longlongsize));
return table;
}

View File

@ -1,10 +1,16 @@
package net.loveruby.cflat.type;
import net.loveruby.cflat.ast.Location;
public class UnionTypeRef extends TypeRef {
protected String name;
public UnionTypeRef(String n) {
name = n;
public UnionTypeRef(String name) {
this(null, name);
}
public UnionTypeRef(Location loc, String name) {
super(loc);
this.name = name;
}
public boolean isUnion() {

View File

@ -1,7 +1,13 @@
package net.loveruby.cflat.type;
import net.loveruby.cflat.ast.Location;
public class UnsignedCharRef extends TypeRef {
public UnsignedCharRef() {
super(null);
}
public UnsignedCharRef(Location loc) {
super(loc);
}
public boolean isUnsignedChar() {

View File

@ -1,7 +1,13 @@
package net.loveruby.cflat.type;
import net.loveruby.cflat.ast.Location;
public class UnsignedIntRef extends TypeRef {
public UnsignedIntRef() {
super(null);
}
public UnsignedIntRef(Location loc) {
super(loc);
}
public boolean isUnsignedInt() {

View File

@ -1,18 +0,0 @@
package net.loveruby.cflat.type;
public class UnsignedLongLongRef extends TypeRef {
public UnsignedLongLongRef() {
}
public boolean isUnsignedLongLong() {
return true;
}
public boolean equals(Object other) {
return (other instanceof UnsignedLongLongRef);
}
public int hashCode() {
return -3;
}
}

View File

@ -1,7 +0,0 @@
package net.loveruby.cflat.type;
public class UnsignedLongLongType extends IntegerType {
public UnsignedLongLongType(int size) {
super(size, false, "ulong_long");
}
}

View File

@ -1,7 +1,13 @@
package net.loveruby.cflat.type;
import net.loveruby.cflat.ast.Location;
public class UnsignedLongRef extends TypeRef {
public UnsignedLongRef() {
super(null);
}
public UnsignedLongRef(Location loc) {
super(loc);
}
public boolean isUnsignedLong() {

View File

@ -1,7 +1,13 @@
package net.loveruby.cflat.type;
import net.loveruby.cflat.ast.Location;
public class UnsignedShortRef extends TypeRef {
public UnsignedShortRef() {
super(null);
}
public UnsignedShortRef(Location loc) {
super(loc);
}
public boolean isUnsignedShort() {

View File

@ -1,10 +1,16 @@
package net.loveruby.cflat.type;
import net.loveruby.cflat.ast.Location;
public class UserTypeRef extends TypeRef {
protected String name;
public UserTypeRef(String n) {
name = n;
public UserTypeRef(String name) {
this(null, name);
}
public UserTypeRef(Location loc, String name) {
super(loc);
this.name = name;
}
public boolean isUserType() {

View File

@ -1,7 +1,13 @@
package net.loveruby.cflat.type;
import net.loveruby.cflat.ast.Location;
public class VoidTypeRef extends TypeRef {
public VoidTypeRef() {
super(null);
}
public VoidTypeRef(Location loc) {
super(loc);
}
public boolean isVoid() {