import java.io.Writer;
import java.io.PrintWriter;

public class SimpleIA32Generator extends AssemblyGenerator {
	public int getSystemIntSize() {
		return 4;
	}

	public int getPointerSize() {
		return 4;
	}

	public int getFunctionSize() {
		return 4;
	}

	PrintWriter out;

	public void generateAssembly(Writer out,
	StaticVariable[] staticVariableDefinitionList,
	Function[] functionDefinitionList) {
		this.out = new PrintWriter(out);

		// プログラムを出力する
		this.out.println(".section .text");
		for (int i = 0; i < functionDefinitionList.length; i++) {
			generateFunction(functionDefinitionList[i]);
		}

		// データの領域を出力する
		this.out.println(".section .bss");
		for (int i = 0; i < staticVariableDefinitionList.length; i++) {
			StaticVariable sv = staticVariableDefinitionList[i];
			this.out.println(".comm " + sv.getName() + ", " + sv.getDataType().getWidth());
		}

		this.out.flush();
	}

	private void generateFunction(Function func) {
		// 関数の開始
		out.println(".globl " + func.getName());
		out.println(func.getName() + ":");
		// 関数内の命令をそれぞれ出力する
		int instNum = func.getInstructionNumber();
		for (int i = 0; i < instNum; i++) {
			generateInstruction(func.getInstruction(i));
		}
		// 関数の終わり
		out.println("stoa.funcend." + func.getName() + ":");
		out.println("\tret");
	}

	private void generateInstruction(Instruction inst) {
		if (inst instanceof NormalExpression) {
			throw new SystemLimitException("NormalExpression not implemented yet");
		} else if (inst instanceof ReturnInstruction) {
			throw new SystemLimitException("ReturnInstruction not implemented yet");
		} else if (inst instanceof ConditionalBranch) {
			throw new SystemLimitException("ConditionalBranch not implemented yet");
		} else if (inst instanceof InfiniteLoop) {
			throw new SystemLimitException("InfiniteLoop not implemented yet");
		} else if (inst instanceof WhileLoop) {
			throw new SystemLimitException("WhileLoop not implemented yet");
		} else if (inst instanceof BreakInstruction) {
			throw new SystemLimitException("BreakInstruction not implemented yet");
		} else if (inst instanceof ContinueInstruction) {
			throw new SystemLimitException("ContinueInstruction not implemented yet");
		}
	}

	private void generateExpressionEvaluation(Expression expr) {
		generateExpressionEvaluation(expr, false);
	}

	private void generateExpressionEvaluation(Expression expr, boolean wantAddress) {
		if (expr instanceof BinaryOperator) {
			throw new SystemLimitException("BinaryOperator not implemented yet");
		} else if (expr instanceof UnaryOperator) {
			throw new SystemLimitException("UnaryOperator not implemented yet");
		} else if (expr instanceof FunctionCallOperator) {
			throw new SystemLimitException("FunctionCallOperator not implemented yet");
		} else if (expr instanceof CastOperator) {
			throw new SystemLimitException("CastOperator not implemented yet");
		} else if (expr instanceof VariableAccess) {
			throw new SystemLimitException("VariableAccess not implemented yet");
		} else if (expr instanceof IntegerLiteral) {
			throw new SystemLimitException("IntegerLiteral not implemented yet");
		} else if (expr instanceof StringLiteral) {
			throw new SystemLimitException("StringLiteral not implemented yet");
		}
	}
}

@@ -267,16 +267,53 @@
 ter out;
+%0A%09private String currentFunctionName;
 %0A%0A%09publi
@@ -984,16 +984,56 @@
 / %E9%96%A2%E6%95%B0%E3%81%AE%E9%96%8B%E5%A7%8B%0A
+%09%09currentFunctionName = func.getName();%0A
 %09%09out.pr
@@ -1050,30 +1050,35 @@
 obl %22 + 
-func.get
+currentFunction
 Name
-()
 );%0A%09%09out
@@ -1086,30 +1086,35 @@
 println(
-func.get
+currentFunction
 Name
-()
  + %22:%22);
@@ -1314,30 +1314,35 @@
 end.%22 + 
-func.get
+currentFunction
 Name
-()
  + %22:%22);
@@ -1473,203 +1473,418 @@
 %0A%09%09%09
-throw new SystemLimitException(%22NormalExpression not implemented yet%22);%0A%09%09%7D else if (inst instanceof ReturnInstruction) %7B%0A%09%09%09throw new SystemLimitException(%22ReturnInstruction not implemented yet%22
+Expression expr = ((NormalExpression)inst).getExpression();%0A%09%09%09generateExpressionEvaluation(expr);%0A%09%09%09out.println(%22%5Ctpop %25eax%22);%0A%09%09%7D else if (inst instanceof ReturnInstruction) %7B%0A%09%09%09ReturnInstruction ret = (ReturnInstruction)inst;%0A%09%09%09if (ret.hasExpression()) %7B%0A%09%09%09%09generateExpressionEvaluation(ret.getExpression());%0A%09%09%09%09out.println(%22%5Ctpop %25eax%22);%0A%09%09%09%7D%0A%09%09%09out.println(%22%5Ctjmp stoa.funcend.%22 + currentFunctionName
 );%0A%09

implement generateInstruction() for NormalExpression and ReturnInstruction