<commit_before>package com.cowlark.sake.backend.make;

import java.io.InputStream;
import java.io.OutputStream;
import java.util.HashMap;
import java.util.Set;
import com.cowlark.sake.BasicBlock;
import com.cowlark.sake.ast.nodes.ExpressionStatementNode;
import com.cowlark.sake.ast.nodes.MethodCallNode;
import com.cowlark.sake.backend.Backend;
import com.cowlark.sake.instructions.ArrayConstructorInstruction;
import com.cowlark.sake.instructions.BooleanConstantInstruction;
import com.cowlark.sake.instructions.DiscardInstruction;
import com.cowlark.sake.instructions.FunctionCallInstruction;
import com.cowlark.sake.instructions.FunctionExitInstruction;
import com.cowlark.sake.instructions.GetGlobalVariableInstruction;
import com.cowlark.sake.instructions.GetLocalVariableInstruction;
import com.cowlark.sake.instructions.GotoInstruction;
import com.cowlark.sake.instructions.IfInstruction;
import com.cowlark.sake.instructions.Instruction;
import com.cowlark.sake.instructions.IntegerConstantInstruction;
import com.cowlark.sake.instructions.MethodCallInstruction;
import com.cowlark.sake.instructions.SetGlobalVariableInstruction;
import com.cowlark.sake.instructions.SetLocalVariableInInstruction;
import com.cowlark.sake.instructions.SetReturnValueInstruction;
import com.cowlark.sake.instructions.StringConstantInstruction;
import com.cowlark.sake.symbols.Function;
import com.cowlark.sake.symbols.LocalVariable;
import com.cowlark.sake.types.Type;

public class MakeBackend extends Backend
{
	private HashMap<LocalVariable, Integer> _variableAllocation =
		new HashMap<LocalVariable, Integer>();
	
	public MakeBackend(OutputStream stream)
    {
		super(stream);
    }
	
	@Override
	public void prologue()
	{
		InputStream is = getClass().getResourceAsStream("sakelib.mk");
		print(is);
	}
	
	@Override
	public void epilogue()
	{
		print("$(call $(sake.globals.<main>))\n");
	}
	
	@Override
	public void compileFunction(Function f)
	{
		print("sake.globals.");
		print(f.getSymbolName().getText());
		print(" := sake.bb.");
		print(f.getEntryBB().getName());
		print("\n");
		
	    super.compileFunction(f);
	}
	
	@Override
	public void compileBasicBlock(BasicBlock bb)
	{
		/* Assign numbers to each variable. */
		
		_variableAllocation.clear();
		int i = 1;
		for (LocalVariable var : bb.getInputVariables())
		{
			_variableAllocation.put(var, i);
			i++;
		}
		
		/* Actually emit the code for the bb. */
		
		print("sake.bb.");
	    print(bb.getName());
	    print(" = ");
	    super.compileBasicBlock(bb);
	    print("\n");
	}
	
	private void emit_output_map()
	{
		for (LocalVariable var : getCurrentBasicBlock().getOutputVariables())
		{
			print(",");
			emit_var(var);
		}
	}
	
	private void emit_string(String s)
	{
		int o = 0;
		while (o < s.length())
		{
			int c = s.codePointAt(o);
			switch (c)
			{
				case '~': print("~T"); break;
				case ',': print("~C"); break;
				case ' ': print("~S"); break;
				
				default:
					print(String.valueOf(Character.toChars(c)));
					break;
			}
			
			o += Character.charCount(c);
		}
	}
	
	private void emit_int(long i)
	{
		if (i < 0)
		{
			print('N');
			i = -i;
		}
		else
			print('P');
		
		String s = Long.toString(i);
		for (int n = s.length()-1; n >= 0; n--)
		{
			print(' ');
			print(s.charAt(n));
		}
	}
	
	private void emit_var(LocalVariable var)
	{
		int id = _variableAllocation.get(var);
		
		print("$(");
		print(id);
		print(")");
	}
	
	@Override
	public void visit(FunctionExitInstruction insn)
	{
	}
	
	@Override
	public void visit(GotoInstruction insn)
	{
		print("$(call sake.bb.");
		print(insn.getTarget().getName());
		emit_output_map();
		print(")");
	}
	
	@Override
	public void visit(IfInstruction insn)
	{
		print("$(call $(if ");
		compileFromIterator();
		print(",sake.bb.");
		print(insn.getPositiveTarget().getName());
		print(",sake.bb.");
		print(insn.getNegativeTarget().getName());
		print(")");
		emit_output_map();
		print(")");
	}
	
	@Override
	public void visit(MethodCallInstruction insn)
	{
		print("$(call sake.method.");
		
		MethodCallNode node = (MethodCallNode) insn.getNode();
		print(node.getMethod().getIdentifier());
		
		print(",");
		compileFromIterator();
		<commit_msg>Minor tweak to reduce unnecessary code bloat in emitted if statements.<commit_after>package com.cowlark.sake.backend.make;

import java.io.InputStream;
import java.io.OutputStream;
import java.util.HashMap;
import java.util.Set;
import com.cowlark.sake.BasicBlock;
import com.cowlark.sake.ast.nodes.ExpressionStatementNode;
import com.cowlark.sake.ast.nodes.MethodCallNode;
import com.cowlark.sake.backend.Backend;
import com.cowlark.sake.instructions.ArrayConstructorInstruction;
import com.cowlark.sake.instructions.BooleanConstantInstruction;
import com.cowlark.sake.instructions.DiscardInstruction;
import com.cowlark.sake.instructions.FunctionCallInstruction;
import com.cowlark.sake.instructions.FunctionExitInstruction;
import com.cowlark.sake.instructions.GetGlobalVariableInstruction;
import com.cowlark.sake.instructions.GetLocalVariableInstruction;
import com.cowlark.sake.instructions.GotoInstruction;
import com.cowlark.sake.instructions.IfInstruction;
import com.cowlark.sake.instructions.Instruction;
import com.cowlark.sake.instructions.IntegerConstantInstruction;
import com.cowlark.sake.instructions.MethodCallInstruction;
import com.cowlark.sake.instructions.SetGlobalVariableInstruction;
import com.cowlark.sake.instructions.SetLocalVariableInInstruction;
import com.cowlark.sake.instructions.SetReturnValueInstruction;
import com.cowlark.sake.instructions.StringConstantInstruction;
import com.cowlark.sake.symbols.Function;
import com.cowlark.sake.symbols.LocalVariable;
import com.cowlark.sake.types.Type;

public class MakeBackend extends Backend
{
	private HashMap<LocalVariable, Integer> _variableAllocation =
		new HashMap<LocalVariable, Integer>();
	
	public MakeBackend(OutputStream stream)
    {
		super(stream);
    }
	
	@Override
	public void prologue()
	{
		InputStream is = getClass().getResourceAsStream("sakelib.mk");
		print(is);
	}
	
	@Override
	public void epilogue()
	{
		print("$(call $(sake.globals.<main>))\n");
	}
	
	@Override
	public void compileFunction(Function f)
	{
		print("sake.globals.");
		print(f.getSymbolName().getText());
		print(" := sake.bb.");
		print(f.getEntryBB().getName());
		print("\n");
		
	    super.compileFunction(f);
	}
	
	@Override
	public void compileBasicBlock(BasicBlock bb)
	{
		/* Assign numbers to each variable. */
		
		_variableAllocation.clear();
		int i = 1;
		for (LocalVariable var : bb.getInputVariables())
		{
			_variableAllocation.put(var, i);
			i++;
		}
		
		/* Actually emit the code for the bb. */
		
		print("sake.bb.");
	    print(bb.getName());
	    print(" = ");
	    super.compileBasicBlock(bb);
	    print("\n");
	}
	
	private void emit_output_map()
	{
		for (LocalVariable var : getCurrentBasicBlock().getOutputVariables())
		{
			print(",");
			emit_var(var);
		}
	}
	
	private void emit_string(String s)
	{
		int o = 0;
		while (o < s.length())
		{
			int c = s.codePointAt(o);
			switch (c)
			{
				case '~': print("~T"); break;
				case ',': print("~C"); break;
				case ' ': print("~S"); break;
				
				default:
					print(String.valueOf(Character.toChars(c)));
					break;
			}
			
			o += Character.charCount(c);
		}
	}
	
	private void emit_int(long i)
	{
		if (i < 0)
		{
			print('N');
			i = -i;
		}
		else
			print('P');
		
		String s = Long.toString(i);
		for (int n = s.length()-1; n >= 0; n--)
		{
			print(' ');
			print(s.charAt(n));
		}
	}
	
	private void emit_var(LocalVariable var)
	{
		int id = _variableAllocation.get(var);
		
		print("$(");
		print(id);
		print(")");
	}
	
	@Override
	public void visit(FunctionExitInstruction insn)
	{
	}
	
	@Override
	public void visit(GotoInstruction insn)
	{
		print("$(call sake.bb.");
		print(insn.getTarget().getName());
		emit_output_map();
		print(")");
	}
	
	@Override
	public void visit(IfInstruction insn)
	{
		print("$(call sake.bb.$(if ");
		compileFromIterator();
		print(",");
		print(insn.getPositiveTarget().getName());
		print(",");
		print(insn.getNegativeTarget().getName());
		print(")");
		emit_output_map();
		print(")");
	}
	
	@Override
	public void visit(MethodCallInstruction insn)
	{
		print("$(call sake.method.");
		
		MethodCallNode node = (MethodCallNode) insn.getNode();
		print(node.getMethod().getIdentifier());
		
		print(",");
		compileFromIterator();
		
{'fraction_non_alphanumeric': 0.14718768502072233, 'fraction_numerical': 0.0011841326228537595, 'mean_word_length': 4.259028642590287, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 11, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2645768', 'n_tokens_mistral': 3177, 'n_tokens_neox': 2893, 'n_words': 504}