/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package IntermediaryCode;

import java.util.HashMap;
import templates.FunctionInterface;

/**
 *
 * @author EUGENIO CARVALHO
 */
public class IRTemplate implements templates.TemplateDescription {

    public HashMap<String, String> Formats() throws Exception {

        return new HashMap<String, String>() {
            {
                String base = "{[PAD(global.position,G.addressLen,' ')]':'}"
                        + "{[T(1)]}"
                        + "{[PAD(block.position,G.addressLen,' ')]':'}"
                        + "{[T(2)]}";

                String end = " {' --'[comment]}"
                        + "{[T(2)]}"
                        + "{'  T< '[type]' >'} "
                        + "{[T(2)]}"
                        + "{[basicBlock]}";

                put("label", "{[T(2)]}{'<'[label]'>'}':'");
                put("alloc", "{[T(3)]} 'alloc ' {[TYPE('p1')]', '} {[numElements]' '} {[p1]}"  + end);

                put("assign", base + "{[dst]}' := '{[p1]' '}{[op]' '}{[p2]}" + end);
                put("pointer_assign", base + "{[dst.pointer]}{[dst]' := '}{[op]' '}{[p1]}" + end);
                put("unary", base + " {[dst]} ' := '{[op]' '}{[p1]}" + end);
//                put("copy", base + "{'('[dst.type]')'} {[dst]} ' := '{[p1]}" + end);
                put("copy", base + " {[dst]} ' := '{[p1]}" + end);
                put("memory", base + " {[type]' '}{[TYPE('p1')]' '}{[p1]}" + end);
                put("jump", base + " 'goto ' {'<'[label]'>'}" + end);
                put("branch", base + " 'if '{[p1]} {' '[op]' '}{[p2]} ' goto ' {'<'[label]'>'}" + end);
//                put("call", base + " {[dst]' := '} 'call <' {[funcname]} '>, ' {[nump]}" + end);
                put("call", base + "'call <' {[funcname]} '>, ' {[nump]}" + end);
                put("return", base + " 'return '{[p1]}" + end);
                put("push_param", base + " 'push_param '{[p1]}" + end);
                put("push_return", base + " 'push_return '{[p1]}" + end);
                put("pop_param", base + " 'pop_param '{[p1]}" + end);
                put("pop_return", base + " 'pop_return '{[p1]}" + end);
            }
        };
    }

    public HashMap<String, FunctionInterface> Functions() throws Exception {
        return new HashMap<String, FunctionInterface>() {
            {
                put("TYPE", (ctx, args) -> {
                    String attr = args.get(0) + ".type";
                    if (!ctx.Has(attr)) {
                        return "";
                    }
                    return "(" + ctx.Get(args.get(0) + ".type") + ")";
                });
            }
        };
    }
}
