mirror of https://github.com/aamine/cbc
* net/loveruby/cflat/compiler/IRGenerator.java: generates IR (intermediate representation) tree (work is still incomplete but commit for logging).
* net/loveruby/cflat/ir: new package to hold IR tree nodes. * net/loveruby/cflat/ir/IRTree.java: new class. * net/loveruby/cflat/ir/Stmt.java: new class. * net/loveruby/cflat/ir/StmtKind.java: new enum. * net/loveruby/cflat/ir/Expr.java: new class. * net/loveruby/cflat/ir/ExprKind.java: new enum. git-svn-id: file:///Users/aamine/c/gitwork/public/cbc/trunk@4136 1b9489fe-b721-0410-924e-b54b9192deb8
This commit is contained in:
parent
5a287a7b48
commit
444c8e1bd9
18
ChangeLog
18
ChangeLog
|
@ -1,3 +1,21 @@
|
|||
Mon Apr 13 01:53:25 2009 Minero Aoki <aamine@loveruby.net>
|
||||
|
||||
* net/loveruby/cflat/compiler/IRGenerator.java: generates IR
|
||||
(intermediate representation) tree (work is still incomplete but
|
||||
commit for logging).
|
||||
|
||||
* net/loveruby/cflat/ir: new package to hold IR tree nodes.
|
||||
|
||||
* net/loveruby/cflat/ir/IRTree.java: new class.
|
||||
|
||||
* net/loveruby/cflat/ir/Stmt.java: new class.
|
||||
|
||||
* net/loveruby/cflat/ir/StmtKind.java: new enum.
|
||||
|
||||
* net/loveruby/cflat/ir/Expr.java: new class.
|
||||
|
||||
* net/loveruby/cflat/ir/ExprKind.java: new enum.
|
||||
|
||||
Sun Apr 12 17:49:19 2009 Minero Aoki <aamine@loveruby.net>
|
||||
|
||||
* net/loveruby/cflat/compiler/TypeChecker.java: split IRGenerator.
|
||||
|
|
|
@ -1,12 +1,14 @@
|
|||
package net.loveruby.cflat.compiler;
|
||||
import net.loveruby.cflat.ast.*;
|
||||
import net.loveruby.cflat.ir.*;
|
||||
import net.loveruby.cflat.type.*;
|
||||
import net.loveruby.cflat.exception.*;
|
||||
import java.util.*;
|
||||
|
||||
class IRGenerator extends Visitor {
|
||||
class IRGenerator extends ASTVisitor<Void, Expr> {
|
||||
protected ErrorHandler errorHandler;
|
||||
protected TypeTable typeTable;
|
||||
private List<Stmt> stmts;
|
||||
|
||||
// #@@range/ctor{
|
||||
public IRGenerator(ErrorHandler errorHandler) {
|
||||
|
@ -15,22 +17,24 @@ class IRGenerator extends Visitor {
|
|||
// #@@}
|
||||
|
||||
protected void compile(StmtNode node) {
|
||||
if (node == null) return;
|
||||
visitStmt(node);
|
||||
}
|
||||
|
||||
protected void compile(ExprNode node) {
|
||||
visitExpr(node);
|
||||
protected Expr compile(ExprNode node) {
|
||||
if (node == null) return null;
|
||||
return visitExpr(node);
|
||||
}
|
||||
|
||||
// FIXME: generate IR tree
|
||||
// #@@range/check_AST{
|
||||
public AST compile(AST ast) throws SemanticException {
|
||||
public IRTree compile(AST ast) throws SemanticException {
|
||||
typeTable = ast.typeTable();
|
||||
for (DefinedVariable var : ast.definedVariables()) {
|
||||
visit(var);
|
||||
}
|
||||
// FIXME: required?
|
||||
//for (DefinedVariable var : ast.definedVariables()) { visit(var); }
|
||||
for (DefinedFunction f : ast.definedFunctions()) {
|
||||
List<Stmt> stmts = new ArrayList<Stmt>();
|
||||
compile(f.body());
|
||||
f.setIR(stmts);
|
||||
}
|
||||
if (errorHandler.errorOccured()) {
|
||||
throw new SemanticException("IR generation failed.");
|
||||
|
@ -39,52 +43,392 @@ class IRGenerator extends Visitor {
|
|||
}
|
||||
// #@@}
|
||||
|
||||
public Void visit(OpAssignNode node) {
|
||||
super.visit(node);
|
||||
if (node.operator().equals("+") || node.operator().equals("-")) {
|
||||
if (node.lhs().type().isDereferable()) {
|
||||
node.setRHS(multiplyPtrBaseSize(node.rhs(), node.lhs()));
|
||||
//
|
||||
// Statement
|
||||
//
|
||||
|
||||
public Void visit(BlockNode node) {
|
||||
for (DefinedVariable var : node.scope().localVariables()) {
|
||||
if (var.initializer() != null) {
|
||||
stmts.add(Stmt.move(Expr.var(var), compile(var.initializer())));
|
||||
}
|
||||
}
|
||||
for (StmtNode s : node.stmts()) {
|
||||
stmts.add(compile(s));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public Void visit(ExprStmtNode node) {
|
||||
stmts.add(Stmt.stmt(compile(node.expr())));
|
||||
return null;
|
||||
}
|
||||
|
||||
public Void visit(ReturnNode node) {
|
||||
stmts.add(Stmt.ret(compile(node.expr())));
|
||||
return null;
|
||||
}
|
||||
|
||||
public Void visit(IfNode node) {
|
||||
stmts.add(Stmt.branch(compile(node.cond()),
|
||||
node.thenLabel(),
|
||||
node.elseLabel()));
|
||||
stmts.add(Stmt.label(node.thenLabel()));
|
||||
compile(node.thenBody());
|
||||
stmts.add(Stmt.label(node.elseLabel()));
|
||||
compile(node.elseBody());
|
||||
stmts.add(Stmt.label(node.endLabel()));
|
||||
return null;
|
||||
}
|
||||
|
||||
// FIXME
|
||||
public Void visit(SwitchNode node) {
|
||||
throw new Error("switch not implemented yet");
|
||||
}
|
||||
|
||||
public Void visit(WhileNode node) {
|
||||
stmts.add(Stmt.branch(compile(node.cond()),
|
||||
node.bodyLabel(), node.endLabel()));
|
||||
stmts.add(Stmt.label(node.begLabel()));
|
||||
compile(node.body());
|
||||
stmts.add(Stmt.branch(compile(node.cond()),
|
||||
node.begLabel(), node.endLabel()));
|
||||
stmts.add(Stmt.label(node.endLabel()));
|
||||
return null;
|
||||
}
|
||||
|
||||
public Void visit(DoWhileNode node) {
|
||||
stmts.add(Stmt.label(node.begLabel()));
|
||||
compile(node.body());
|
||||
stmts.add(Stmt.branch(compile(node.cond()),
|
||||
node.begLabel(), node.endLabel()));
|
||||
stmts.add(Stmt.label(node.endLabel()));
|
||||
return null;
|
||||
}
|
||||
|
||||
public Void visit(ForNode node) {
|
||||
compile(node.init());
|
||||
stmts.add(Stmt.branch(compile(node.cond()),
|
||||
node.begLabel(), node.endLabel()));
|
||||
stmts.add(node.begLabel());
|
||||
compile(node.body());
|
||||
stmts.add(node.continueLabel());
|
||||
compile(node.incr());
|
||||
stmts.add(Stmt.branch(compile(node.cond()),
|
||||
node.begLabel(), node.endLabel()));
|
||||
stmts.add(node.endLabel());
|
||||
return null;
|
||||
}
|
||||
|
||||
public Void visit(BreakNode node) {
|
||||
stmts.add(Stmt.jump(currentBreakLabel()));
|
||||
return null;
|
||||
}
|
||||
|
||||
public Void visit(ContinueNode node) {
|
||||
stmts.add(Stmt.jump(currentContinueLabel()));
|
||||
return null;
|
||||
}
|
||||
|
||||
public Void visit(GotoNode node) {
|
||||
stmts.add(Stmt.jump(node.label()));
|
||||
return null;
|
||||
}
|
||||
|
||||
public Void visit(LabelNode node) {
|
||||
stmts.add(node.label());
|
||||
compile(node.stmt());
|
||||
return null;
|
||||
}
|
||||
|
||||
//
|
||||
// RHS Expression
|
||||
//
|
||||
|
||||
// #@@range/BinaryOpNode{
|
||||
public Void visit(BinaryOpNode node) {
|
||||
super.visit(node);
|
||||
public Expr visit(BinaryOpNode node) {
|
||||
ExprKind op = binOp(node.operator());
|
||||
Expr left = compile(node.left());
|
||||
Expr right = compile(node.right());
|
||||
if (node.operator().equals("+") || node.operator().equals("-")) {
|
||||
if (node.left().type().isDereferable()) {
|
||||
node.setRight(multiplyPtrBaseSize(node.right(), node.left()));
|
||||
right = multiplyPtrBaseSize(right, node.left());
|
||||
}
|
||||
else if (node.right().type().isDereferable()) {
|
||||
node.setLeft(multiplyPtrBaseSize(node.left(), node.right()));
|
||||
left = multiplyPtrBaseSize(left, node.right());
|
||||
}
|
||||
}
|
||||
return null;
|
||||
return Expr.bin(op, left, right);
|
||||
}
|
||||
// #@@}
|
||||
|
||||
protected BinaryOpNode multiplyPtrBaseSize(ExprNode expr, ExprNode ptr) {
|
||||
return new BinaryOpNode(expr, "*", ptrBaseSize(ptr));
|
||||
public Expr visit(AssignNode node) {
|
||||
Expr tmp = Expr.tmp();
|
||||
return Expr.seq(
|
||||
Stmt.seq(
|
||||
Stmt.move(tmp, compile(node.rhs())),
|
||||
Stmt.move(compileLHS(node.lhs()), tmp)
|
||||
),
|
||||
tmp);
|
||||
}
|
||||
|
||||
protected IntegerLiteralNode ptrBaseSize(ExprNode ptr) {
|
||||
return integerLiteral(ptr.location(),
|
||||
typeTable.ptrDiffTypeRef(),
|
||||
ptr.type().baseType().size());
|
||||
public Expr visit(OpAssignNode node) {
|
||||
Expr r = Expr.tmp();
|
||||
Expr l = Expr.tmp();
|
||||
return Expr.seq(
|
||||
Stmt.seq(
|
||||
Stmt.move(r, compileOpAssignRHS(node.rhs()),
|
||||
Stmt.move(l, compileLHS(node.lhs())),
|
||||
Stmt.move(Expr.mem(l),
|
||||
Expr.bin(binOp(node.operator()),
|
||||
Expr.mem(l), r))
|
||||
),
|
||||
r);
|
||||
}
|
||||
|
||||
protected IntegerLiteralNode integerLiteral(Location loc, TypeRef ref, long n) {
|
||||
IntegerLiteralNode node = new IntegerLiteralNode(loc, ref, n);
|
||||
bindType(node.typeNode());
|
||||
return node;
|
||||
private Expr compileOpAssignRHS(String op, ExprNode rhs, ExprNode lhs) {
|
||||
if ((op.equals("+") || op.equals("-")) && lhs.type().isDereferable()) {
|
||||
return multiplyPtrBaseSize(compile(rhs), lhs);
|
||||
}
|
||||
else {
|
||||
return compile(rhs);
|
||||
}
|
||||
}
|
||||
|
||||
protected void bindType(TypeNode t) {
|
||||
t.setType(typeTable.get(t.typeRef()));
|
||||
protected Expr multiplyPtrBaseSize(Expr expr, ExprNode ptr) {
|
||||
return Expr.bin(ExprKind.MUL, expr, ptrBaseSize(ptr));
|
||||
}
|
||||
|
||||
protected void error(Node n, String msg) {
|
||||
protected Expr ptrBaseSize(ExprNode ptr) {
|
||||
Type t = typeTable.ptrDiffType();
|
||||
Location loc = ptr.location();
|
||||
return Expr.const(ptr.type().baseType().size());
|
||||
}
|
||||
|
||||
public Expr visit(LogicalAndNode node) {
|
||||
Expr l = Expr.tmp();
|
||||
Expr result = Expr.tmp();
|
||||
return Expr.seq(
|
||||
Stmt.seq(
|
||||
Stmt.move(l, compile(node.left())),
|
||||
Stmt.branch(l, node.thenLabel(), node.elseLabel()),
|
||||
Stmt.label(node.thenLabel()),
|
||||
Stmt.move(result, l),
|
||||
Stmt.label(node.elseLabel()),
|
||||
Stmt.move(result, compile(node.right()))
|
||||
),
|
||||
result);
|
||||
}
|
||||
|
||||
public Expr visit(LogicalOrNode node) {
|
||||
Expr l = Expr.tmp();
|
||||
Expr result = Expr.tmp();
|
||||
return Expr.seq(
|
||||
Stmt.seq(
|
||||
Stmt.move(l, compile(node.left())),
|
||||
Stmt.branch(l, node.elseLabel(), node.thenLabel()),
|
||||
Stmt.label(node.thenLabel()),
|
||||
Stmt.move(result, l),
|
||||
Stmt.label(node.elseLabel()),
|
||||
Stmt.move(result, compile(node.right()))
|
||||
),
|
||||
result);
|
||||
}
|
||||
|
||||
public Expr visit(CondExprNode node) {
|
||||
Expr result = Expr.tmp();
|
||||
return Expr.seq(
|
||||
Stmt.seq(
|
||||
Stmt.branch(compile(node.cond()),
|
||||
node.thenLabel(), node.elseLabel()),
|
||||
Stmt.label(node.thenLabel()),
|
||||
Stmt.move(result, compile(node.thenExpr())),
|
||||
Stmt.label(node.elseLabel()),
|
||||
Stmt.move(result, compile(node.elseExpr()))
|
||||
),
|
||||
result);
|
||||
}
|
||||
|
||||
public Expr visit(FuncallNode node) {
|
||||
List<Expr> args = new ArrayList<Expr>();
|
||||
for (ExprNode a : node.arguments()) {
|
||||
args.add(compile(a));
|
||||
}
|
||||
return Expr.call(compile(node.expr()), args);
|
||||
}
|
||||
|
||||
public Expr visit(UnaryOpNode node) {
|
||||
if (node.operator().equals("+")) {
|
||||
return compile(node.expr());
|
||||
}
|
||||
else {
|
||||
return Expr.uni(uniOp(node.operator()), compile(node.expr()));
|
||||
}
|
||||
}
|
||||
|
||||
public Expr visit(PrefixOpNode node) {
|
||||
Expr lhs = Expr.tmp();
|
||||
return Expr.seq(
|
||||
Stmt.seq(
|
||||
Stmt.move(lhs, compileLHS(node.expr())),
|
||||
Stmt.move(Expr.mem(lhs),
|
||||
Expr.bin(uniOp(node.operator()),
|
||||
Expr.mem(lhs),
|
||||
Expr.const(1)))
|
||||
),
|
||||
Expr.mem(lhs));
|
||||
}
|
||||
|
||||
public Expr visit(SuffixOpNode node) {
|
||||
Expr lhs = Expr.tmp();
|
||||
Expr save = Expr.tmp();
|
||||
return Expr.seq(
|
||||
Stmt.seq(
|
||||
Stmt.move(lhs, compileLHS(node.expr())),
|
||||
Stmt.move(save, Expr.mem(lhs));
|
||||
Stmt.move(Expr.mem(lhs),
|
||||
Expr.bin(uniOp(node.operator()),
|
||||
Expr.mem(lhs),
|
||||
Expr.const(1)))
|
||||
),
|
||||
Expr.mem(save));
|
||||
}
|
||||
|
||||
public Expr visit(AddressNode node) {
|
||||
return compileLHS(node.expr());
|
||||
}
|
||||
|
||||
public Expr visit(SizeofExprNode node) {
|
||||
return Expr.const(node.expr().type().allocSize());
|
||||
}
|
||||
|
||||
public Expr visit(SizeofTypeNode node) {
|
||||
return Expr.const(node.operand().allocSize());
|
||||
}
|
||||
|
||||
public Expr visit(IntegerLiteralNode node) {
|
||||
return Expr.const(node.value());
|
||||
}
|
||||
|
||||
public Expr visit(StringLiteralNode node) {
|
||||
return Expr.name(node.entry());
|
||||
}
|
||||
|
||||
//
|
||||
// Assignable Expression as RHS
|
||||
//
|
||||
|
||||
public Expr visit(ArefNode node) {
|
||||
return Expr.mem(compileLHS(node));
|
||||
}
|
||||
|
||||
public Expr visit(MemberNode node) {
|
||||
Expr a = Expr.add(Expr.const(node.offset()), compileLHS(node.expr()));
|
||||
return node.shouldEvaluatedToAddress() ? a : Expr.deref(a);
|
||||
}
|
||||
|
||||
public Expr visit(PtrMemberNode node) {
|
||||
Expr addr = Expr.add(Expr.const(node.offset()), compile(node.expr()));
|
||||
return node.shouldEvaluatedToAddress() ? addr : Expr.deref(addr);
|
||||
}
|
||||
|
||||
public Expr visit(DereferenceNode node) {
|
||||
return Expr.deref(compile(node.expr()));
|
||||
}
|
||||
|
||||
public Expr visit(VariableNode node) {
|
||||
return Expr.var(node.variable());
|
||||
}
|
||||
|
||||
//
|
||||
// Assignable Expression as LHS
|
||||
//
|
||||
|
||||
public Expr compileLHS(ExprNode node) {
|
||||
node.acceptLHS(this);
|
||||
}
|
||||
|
||||
public Expr visitLHS(VariableNode node) {
|
||||
return addressOf(node);
|
||||
}
|
||||
|
||||
public Expr visitLHS(ArefNode node) {
|
||||
return Expr.add(
|
||||
Expr.mul(
|
||||
Expr.const(node.elementSize()),
|
||||
compileArrayIndex(node)),
|
||||
compile(node.baseExpr));
|
||||
}
|
||||
|
||||
private Expr compileArrayIndex(ArefNode node) {
|
||||
if (node.isMultiDimension()) {
|
||||
return Expr.add(
|
||||
compile(node.index()),
|
||||
Expr.mul(
|
||||
Expr.const(node.length()),
|
||||
compileArrayIndex((ArefNode)node.expr())));
|
||||
}
|
||||
else {
|
||||
return compile(node.index());
|
||||
}
|
||||
}
|
||||
|
||||
public Expr visitLHS(MemberNode node) {
|
||||
return Expr.add(
|
||||
Expr.const(node.offset()),
|
||||
compileLHS(node.expr()));
|
||||
}
|
||||
|
||||
public Expr visitLHS(PtrMemberNode node) {
|
||||
return Expr.add(
|
||||
Expr.const(node.offset()),
|
||||
compile(node.expr()));
|
||||
}
|
||||
|
||||
public Expr visitLHS(DereferenceNode node) {
|
||||
return compile(node.expr());
|
||||
}
|
||||
|
||||
//
|
||||
// Utilities
|
||||
//
|
||||
|
||||
private Expr addressOf(VariableNode node) {
|
||||
}
|
||||
|
||||
private Expr addressOf(StringLiteralNode node) {
|
||||
}
|
||||
|
||||
private ExprKind uniOp(String op) {
|
||||
if (op.equals("-")) return ExprKind.UMINUS;
|
||||
if (op.equals("~")) return ExprKind.NOT;
|
||||
if (op.equals("!")) return ExprKind.LNOT;
|
||||
if (op.equals("*")) return ExprKind.DEREF;
|
||||
if (op.equals("++")) return ExprKind.ADD;
|
||||
if (op.equals("--")) return ExprKind.SUB;
|
||||
}
|
||||
|
||||
// FIXME: signed, arithmetic shift
|
||||
private ExprKind binOp(String op) {
|
||||
if (op.equals("+")) return ExprKind.ADD;
|
||||
if (op.equals("-")) return ExprKind.SUB;
|
||||
if (op.equals("*")) return ExprKind.MUL;
|
||||
if (op.equals("/")) return ExprKind.DIV;
|
||||
if (op.equals("%")) return ExprKind.MOD;
|
||||
if (op.equals("&")) return ExprKind.AND;
|
||||
if (op.equals("|")) return ExprKind.OR;
|
||||
if (op.equals("^")) return ExprKind.XOR;
|
||||
if (op.equals("<<")) return ExprKind.LSHIFT;
|
||||
if (op.equals(">>")) return ExprKind.RSHIFT;
|
||||
if (op.equals("==")) return ExprKind.EQ;
|
||||
if (op.equals("!=")) return ExprKind.NEQ;
|
||||
if (op.equals("<")) return ExprKind.LT;
|
||||
if (op.equals("<=")) return ExprKind.LTEQ;
|
||||
if (op.equals(">")) return ExprKind.GT;
|
||||
if (op.equals(">=")) return ExprKind.GTEQ;
|
||||
}
|
||||
|
||||
private void error(Node n, String msg) {
|
||||
errorHandler.error(n.location(), msg);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,82 @@
|
|||
package net.loveruby.cflat.ir;
|
||||
|
||||
public class Expr {
|
||||
protected ExprKind kind;
|
||||
protected Expr x, y;
|
||||
protected List<Expr> args;
|
||||
protected long value;
|
||||
protected ConstantEntry entry;
|
||||
protected Entity entity;
|
||||
protected Stmt stmt;
|
||||
|
||||
static public const(long value) {
|
||||
return new Expr(ExprKind.CONST, null, null, null, value, null, null, null);
|
||||
}
|
||||
|
||||
static public name(ConstantEntry entry) {
|
||||
return new Expr(ExprKind.NAME, null, null, null, 0, entry, null, null);
|
||||
}
|
||||
|
||||
static public var(Entity entity) {
|
||||
return new Expr(ExprKind.VAR, null, null, null, 0, null, entity, null);
|
||||
}
|
||||
|
||||
static public varAddr(Entity entity) {
|
||||
return new Expr(ExprKind.VARADDR, null, null, null, 0, null, entity, null);
|
||||
}
|
||||
|
||||
static public call(Expr f, List<Expr> args) {
|
||||
return new Expr(ExprKind.CALL, f, null, args, 0, null, null, null);
|
||||
}
|
||||
|
||||
static public uni(ExprKind t, Expr expr) {
|
||||
return new Expr(t, expr, null, null, 0, null, null, null);
|
||||
}
|
||||
|
||||
static public bin(ExprKind t, Expr left, Expr right) {
|
||||
return new Expr(t, left, right, null, 0, null, null, null);
|
||||
}
|
||||
|
||||
static public add(Expr left, Expr right) {
|
||||
return new Expr(ExprKind.ADD, left, right, null, 0, null, null, null);
|
||||
}
|
||||
|
||||
static public mul(Expr left, Expr right) {
|
||||
return new Expr(ExprKind.MUL, left, right, null, 0, null, null, null);
|
||||
}
|
||||
|
||||
static public seq(Stmt s, Expr e) {
|
||||
return new Expr(ExprKind.SEQ, e, null, null, 0, nul, null, s);
|
||||
}
|
||||
|
||||
public Expr(ExprKind k, Expr x, Expr y, List<Expr> args,
|
||||
long value, ConstantEntry entry, Entity entity, Stmt stmt) {
|
||||
this.kind = k;
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.args = args;
|
||||
this.value = value;
|
||||
this.entry = entry;
|
||||
this.entity = entity;
|
||||
this.stmt = stmt;
|
||||
}
|
||||
|
||||
// as primary
|
||||
public long value() { return value; }
|
||||
public ConstantEntry entry() { return entry; }
|
||||
public Entity entity() { return entity; }
|
||||
|
||||
// as unary
|
||||
public Expr expr() { return x; }
|
||||
|
||||
// as binary
|
||||
public Expr left() { return x; }
|
||||
public Expr right() { return y; }
|
||||
|
||||
// as seq
|
||||
public Stmt stmt() { return stmt; }
|
||||
|
||||
// as call
|
||||
public Expr function() { return x; }
|
||||
public List<Expr> args() { return args; }
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
package net.loveruby.cflat.ir;
|
||||
|
||||
public enum ExprKind {
|
||||
// primary
|
||||
CONST, // integer constant
|
||||
NAME, // assembly name (string literal, global variable)
|
||||
VAR, // variable
|
||||
VARADDR, // address of variable
|
||||
// unary
|
||||
UMINUS, // unary minus
|
||||
NOT, // bitwise not
|
||||
LNOT, // logical not
|
||||
DEREF, // dereference
|
||||
// binary
|
||||
ADD, // addition
|
||||
SUB, // subtract
|
||||
MUL, // multiplication
|
||||
DIV, // division
|
||||
MOD, // modulo
|
||||
AND, // bitwise and
|
||||
OR, // bitwise or
|
||||
XOR, // bitwise xor
|
||||
LSHIFT, // left shift
|
||||
RSHIFT, // right shift
|
||||
EQ, // ==
|
||||
NEQ, // !=
|
||||
GT, // >
|
||||
GTEQ, // >=
|
||||
LT, // <
|
||||
LTEQ, // <=
|
||||
// seq
|
||||
SEQ; // expression sequence (for +=, ++, --)
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
package net.loveruby.cflat.ir;
|
||||
|
||||
public class IRTree {
|
||||
protected Location source;
|
||||
protected ToplevelScope scope;
|
||||
protected ConstantTable constantTable;
|
||||
protected Set<DefinedVariable> defvars;
|
||||
protected Set<DefinedFunction> defuns;
|
||||
|
||||
public IRTree(Location source,
|
||||
ToplevelScope scope,
|
||||
ConstantTable constants,
|
||||
Set<DefinedVariable> defvars,
|
||||
Set<DefinedFunction> defuns) {
|
||||
this.source = source;
|
||||
this.scope = scope;
|
||||
this.constants = constants;
|
||||
this.defvars = defvars;
|
||||
this.defuns = defuns;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,82 @@
|
|||
package net.loveruby.cflat.ir;
|
||||
|
||||
public class Stmt {
|
||||
protected StmtKind kind;
|
||||
protected Expr x, y;
|
||||
protected Stmt car, cdr;
|
||||
protected Label thenDest, elseDest;
|
||||
|
||||
static public Stmt move(Expr lhs, Expr rhs) {
|
||||
return new Stmt(StmtKind.MOVE, lhs, rhs, null, null);
|
||||
}
|
||||
|
||||
static public Stmt branch(Expr cond, Label thenDest, elseDest) {
|
||||
return new Stmt(StmtKind.BRANCH, cond, null, null, null, thenDest, elseDest);
|
||||
}
|
||||
|
||||
static public Stmt stmt(Expr expr) {
|
||||
return new Stmt(StmtKind.EXPR, expr, null, null, null, null, null);
|
||||
}
|
||||
|
||||
static public Stmt ret(Expr expr) {
|
||||
return new Stmt(StmtKind.RETURN, expr, null, null, null, null, null);
|
||||
}
|
||||
|
||||
static public Stmt label(Label label) {
|
||||
return new Stmt(StmtKind.LABEL, null, null, null, null, label, null);
|
||||
}
|
||||
|
||||
static public Stmt seq(Stmt car, Stmt cdr) {
|
||||
return new Stmt(StmtKind.SEQ, null, null, car, cdr, null, null);
|
||||
}
|
||||
|
||||
static public Stmt seq(Stmt s1, Stmt s2, Stmt s3) {
|
||||
return seq(s1, seq(s2, s3));
|
||||
}
|
||||
|
||||
static public Stmt seq(Stmt s1, Stmt s2, Stmt s3, Stmt s4) {
|
||||
return seq(s1, seq(s2, seq(s3, s4)));
|
||||
}
|
||||
|
||||
static public Stmt seq(Stmt s1, Stmt s2, Stmt s3, Stmt s4, Stmt s5) {
|
||||
return seq(s1, seq(s2, seq(s3, seq(s4, s5))));
|
||||
}
|
||||
|
||||
static public Stmt seq(Stmt s1, Stmt s2, Stmt s3, Stmt s4, Stmt s5, Stmt s6) {
|
||||
return seq(s1, seq(s2, seq(s3, seq(s4, seq(s5, s6)))));
|
||||
}
|
||||
|
||||
static public Stmt seq(Stmt s1, Stmt s2, Stmt s3, Stmt s4, Stmt s5, Stmt s6, Stmt s7) {
|
||||
return seq(s1, seq(s2, seq(s3, seq(s4, seq(s5, seq(s6, s7))))));
|
||||
}
|
||||
|
||||
public Stmt(StmtKind kind, Expr x, Expr y,
|
||||
Stmt car, Stmt cdr,
|
||||
Label thenDest, Label elseDest) {
|
||||
this.kind = kind;
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.car = car;
|
||||
this.cdr = cdr;
|
||||
this.thenDest = thenDest;
|
||||
this.elseDest = elseDest;
|
||||
}
|
||||
|
||||
public StmtKind kind() { return kind; }
|
||||
|
||||
// as expr-statement, return
|
||||
public Expr expr() { return x; }
|
||||
|
||||
// as move
|
||||
public Expr lhs() { return x; }
|
||||
public Expr rhs() { return y; }
|
||||
|
||||
// as branchIf
|
||||
public Expr cond() { return x; }
|
||||
public Label thenDest() { return thenDest; }
|
||||
public Label elseDest() { return elseDest; }
|
||||
|
||||
// as seq
|
||||
public Stmt car() { return car; }
|
||||
public Stmt cdr() { return cdr; }
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
package net.loveruby.cflat.ir;
|
||||
|
||||
public enum StmtKind {
|
||||
MOVE, // assignment
|
||||
EXPR, // expression statement
|
||||
BRANCH, // conditional jump
|
||||
RETURN, // return
|
||||
LABEL; // label
|
||||
}
|
Loading…
Reference in New Issue