Convenții de programare

De la WikiLabs

La laboratorul de POO se va puncta și modul în care un program este paginat, tabulat, modul în care sunt denumite clasele, metodele și variabilele, și, în general, modul în care codul este structurat. Regulile care trebuie respectate sunt:

  • se evită utilizarea de inner-class, deci într-un fişier Java se definește o singura clasă;
  • segmentele fişierului apar în următoarea ordine:
    • comentariul de introducere (header) care descrie pe scurt rolul clasei;
    • declaraţia de pachet (dacă există);
    • directivele de import;
    • declaraţia de clasă / interfaţă;
    • declaraţiile de câmpuri, toate identate cu un tab, în următoarea ordine:
      • constante de clasă;
      • câmpuri statice;
      • câmpuri dinamice;
    • constructori, de la cel mai puţin complex la cel mai complex (neidentate);
    • metode (neidentate);
    • comentariul de final (footer);
  • metoda main, dacă există, este plasată între constructori şi metode;
  • pentru instrucţiuni if / do-while / for / case, şi pentru blocul metodelor, acolada care deschide blocul de instrucţiuni se află pe aceeaşi linie cu instrucţiunea / declaraţia iniţială iar acolada de final se află pe o linie separată, pe aceeaşi coloana cu prima literă din instrucţiune / declaraţie;
  • un bloc de instrucţiuni este identat cu un tab faţă de nivelul imediat superior;
  • numele de clase, implicit constructori, încep cu majusculă.
  • numele de metode încep cu litera mică;
  • numele de câmpuri dinamice încep cu litera "m";
  • numele de câmpuri statice încep cu litera "s";
  • numele de constante sunt scrise numai cu majuscule, cuvintele fiind desparţite prin "_";
  • argumentele și variabilele locale încep cu literă mică;
  • numele trebuie să fie cât mai sugestive în ceea ce priveşte scopul, pentru a evita comentariile excesive;
  • este permisă introducerea unei linii goale, dacă prin acest lucru se realizează o segregare naturală a elementelor.

Aceste convenții de scriere a codului sunt doar un minim necesar(și obligatoriu) pentru laboratorul de POO. Pentru cei ce vor să cunoască tot setul de convenții recomandat de Oracle, îl pot găsi online.

Exemplu (atenție, acest program nu va funcționa de sine stătător deoarece este parte a unui proiect):

//------------------------------------------------------------------------------
//
//		This is the title of the Project
//			- Assembler -
//
//------------------------------------------------------------------------------
//
//  The role of this class is to provide an example as to how a Java
// class is structured and how the code is written. It provides examples
// for naming conventions and code alignment.
//
//------------------------------------------------------------------------------
package ro.pub.arh.beam.assembler;

import ro.pub.arh.beam.assembler.structs.*;
import java.io.*;
import java.util.Vector;
import ro.pub.arh.beam.structs.*;
import ubiCORE.jroot.common.utils.ErrorCode;
import ro.pub.arh.beam.common.HexConverter;

public class Assembler{

    public static final int REGISTER_COUNT = 32;
    public static final String INSTRUCTION_SEPARATOR = "\\|";
    public static final String OPERAND_SEPARATOR = "\\s+|\\s*\\,\\s*";
    
    private static PrintStream sDumpStream = System.out;

    private String mFileName;

    private int mCurrentAddress;
    private int mCurrentLine;

    private Program mProgram;
    private Function mFunction;
    private int mEntityIndex;


public Assembler(String fileName){
    mFileName = fileName;
    mCurrentAddress = 0;
    mCurrentLine = 1;
}


public static void main(String[] args){
    try{
        new Assembler(args[0]).run();
    }catch(ArrayIndexOutOfBoundsException aiobe){
        out("File is empty or no file specified.");
    }catch(Exception e){
        e.printStackTrace();
        out("Assembly error: " + e.getMessage());
    }
}


public void run() throws IOException, ErrorCode{
    BufferedReader reader = new BufferedReader(new FileReader(mFileName));
    String line;
    Vector<Instruction> instructions = null;
    boolean atLeastOneError = false;

    mEntityIndex = 0;
    mProgram = new Program(mFileName);
    do{
        line = reader.readLine();
        if(line == null){
            mProgram.add(mFunction);
            break;
        }
        line = trimWhiteSpaces(line);
        try{
            instructions = null;
            instructions = processLine(line);

            if(instructions != null){
                mFunction.addAll(instructions);
                mCurrentAddress += Instruction.INSTRUCTION_LOCATION_COUNT;
            }
        }catch(RuntimeException re){
            out("Line " + mCurrentLine + ": " + re.getMessage());
            //re.printStackTrace();
            atLeastOneError = true;
        }
        
        currentLine++;
    }while(true);

    if(atLeastOneError){
        out("Finished with errors.");
        throw new RuntimeException("Assembly failed.");
    }
    
    out("No syntax errors.");
    //placeIRQHandler("irq_handler", MachineConstants.IRQ_HANDLER_ADDR);
    replaceJumpLabels();
    buildLineSeeker();

    out("Assembly succesfull!");

    mProgram.sort();

}

private Vector<Instruction> processLine(String line){
//...
}

private String trimWhiteSpaces(String line){
    line = line.substring(0, line.indexOf("//") == -1 ? line.length() : line.indexOf("//"));
    line = line.substring(0, line.indexOf(";") == -1 ? line.length() : line.indexOf(";"));
    line = line.trim();
    line = line.replaceAll("\\s+", " ");
    return line;
}

private int getValueOfString(String number){
    int value;

    try{
        if(number.startsWith("0x")){
            value = Integer.parseInt(number.substring(2), 16);
        }else{
            value = Integer.parseInt(number);
        }
    }catch(NumberFormatException nfe){
        throw new RuntimeException("Invalid new code address");
    }

    if(value % 4 != 0){
        throw new RuntimeException("Invalid new code address " + mCurrentLine + ". Address must divide by 4.");
    }
    return value;
}

private void replaceJumpLabels(){
    int address = 0;
    Instruction instruction = null;

    for(int i=0; i<mProgram.size(); i++){
        Function function = mProgram.elementAt(i);
        for(int j=0; j<mProgram.elementAt(i).size(); j++){
            instruction = function.elementAt(j);
            if(instruction.getLabel() != null){
                String label = extractLabel(instruction.getLabel());
                if(instruction.isCall()){
                    address = mProgram.findAddressOfFunction(label);
                }else if(instruction.isAbsoluteJump()){
                    address = mProgram.findAddressOfLabel(label);
                }else{
                    address = mProgram.findAddressOfLabel(label) - instruction.getAddress();
                }

                instruction.setLabelAddress(offsetAddress(address, instruction.getLabel()));
            }
        }
    }
}

}
//------------------------------------------------------------------------------
//      Change History:
//      $Log: Assembler.java,java $