Convenții de programare: Diferență între versiuni

De la WikiLabs
Jump to navigationJump to search
Fără descriere a modificării
Fără descriere a modificării
 
(Nu s-a afișat o versiune intermediară efectuată de același utilizator)
Linia 13: Linia 13:
** metode (neidentate);
** metode (neidentate);
** comentariul de final (footer);
** comentariul de final (footer);
* toate segmentele fişierului sunt despărţite printr-o linie-comentariu ce apare inclusiv între constructori şi între metode;
* metoda main, dacă există, este plasată între constructori şi metode;
* 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;
* 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;
Linia 19: Linia 18:
* numele de clase, implicit constructori, încep cu majusculă.
* numele de clase, implicit constructori, încep cu majusculă.
* numele de metode încep cu litera mică;
* numele de metode încep cu litera mică;
* numele de câmpuri î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 "_";
* numele de constante sunt scrise numai cu majuscule, cuvintele fiind desparţite prin "_";
* argumentele și variabilele locale ale metodelor sunt declarate imediat sub declaraţia metodei, neidentate, şi încep cu caracterul “_”, având a doua literă mică. Excepţie fac contorii de cicli: i, j, k;
* 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;
* 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.
* este permisă introducerea unei linii goale, dacă prin acest lucru se realizează o segregare naturală a elementelor.
Linia 43: Linia 43:
package ro.pub.arh.beam.assembler;
package ro.pub.arh.beam.assembler;


//------------------------------------------------------------------------------
import ro.pub.arh.beam.assembler.structs.*;
import ro.pub.arh.beam.assembler.structs.*;
import java.io.*;
import java.io.*;
Linia 50: Linia 49:
import ubiCORE.jroot.common.utils.ErrorCode;
import ubiCORE.jroot.common.utils.ErrorCode;
import ro.pub.arh.beam.common.HexConverter;
import ro.pub.arh.beam.common.HexConverter;
//------------------------------------------------------------------------------
 
public class Assembler{
public class Assembler{


Linia 57: Linia 56:
     public static final String OPERAND_SEPARATOR = "\\s+|\\s*\\,\\s*";
     public static final String OPERAND_SEPARATOR = "\\s+|\\s*\\,\\s*";
      
      
     private static PrintStream dumpStream = System.out;
     private static PrintStream sDumpStream = System.out;
 
    private String mFileName;


     private String fileName;
     private int mCurrentAddress;
    private int mCurrentLine;


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


    private Program program;
    private Function function;
    private int entityIndex;


//------------------------------------------------------------------------------
public Assembler(String fileName){
public Assembler(String _fileName){
     mFileName = fileName;
     fileName = _fileName;
     mCurrentAddress = 0;
     currentAddress = 0;
     mCurrentLine = 1;
     currentLine = 1;
}
}


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


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


     entityIndex = 0;
     mEntityIndex = 0;
     program = new Program(fileName);
     mProgram = new Program(mFileName);
     do{
     do{
         _line = _reader.readLine();
         line = reader.readLine();
         if(_line == null){
         if(line == null){
             program.add(function);
             mProgram.add(mFunction);
             break;
             break;
         }
         }
         _line = trimWhiteSpaces(_line);
         line = trimWhiteSpaces(line);
         try{
         try{
             _instructions = null;
             instructions = null;
             _instructions = processLine(_line);
             instructions = processLine(line);


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


     if(_atLeastOneError){
     if(atLeastOneError){
         out("Finished with errors.");
         out("Finished with errors.");
         throw new RuntimeException("Assembly failed.");
         throw new RuntimeException("Assembly failed.");
Linia 133: Linia 131:
     out("Assembly succesfull!");
     out("Assembly succesfull!");


     program.sort();
     mProgram.sort();


}
}


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


//------------------------------------------------------------------------------
private String trimWhiteSpaces(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.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.trim();
     line = line.replaceAll("\\s+", " ");
     _line = _line.replaceAll("\\s+", " ");
     return line;
     return _line;
}
}


//------------------------------------------------------------------------------
private int getValueOfString(String number){
private int getValueOfString(String _number){
    int value;
int _value;
 
//--
     try{
     try{
         if(_number.startsWith("0x")){
         if(number.startsWith("0x")){
             _value = Integer.parseInt(_number.substring(2), 16);
             value = Integer.parseInt(number.substring(2), 16);
         }else{
         }else{
             _value = Integer.parseInt(_number);
             value = Integer.parseInt(number);
         }
         }
     }catch(NumberFormatException _nfe){
     }catch(NumberFormatException nfe){
         throw new RuntimeException("Invalid new code address");
         throw new RuntimeException("Invalid new code address");
     }
     }


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


//------------------------------------------------------------------------------
private void replaceJumpLabels(){
private void replaceJumpLabels(){
int _address = 0;
    int address = 0;
Instruction _instruction = null;
    Instruction instruction = null;
//--
 
     for(int i=0; i<program.size(); i++){
     for(int i=0; i<mProgram.size(); i++){
         Function _function = program.elementAt(i);
         Function function = mProgram.elementAt(i);
         for(int j=0; j<program.elementAt(i).size(); j++){
         for(int j=0; j<mProgram.elementAt(i).size(); j++){
             _instruction = _function.elementAt(j);
             instruction = function.elementAt(j);
             if(_instruction.getLabel() != null){
             if(instruction.getLabel() != null){
                 String _label = extractLabel(_instruction.getLabel());
                 String label = extractLabel(instruction.getLabel());
                 if(_instruction.isCall()){
                 if(instruction.isCall()){
                     _address = program.findAddressOfFunction(_label);
                     address = mProgram.findAddressOfFunction(label);
                 }else if(_instruction.isAbsoluteJump()){
                 }else if(instruction.isAbsoluteJump()){
                     _address = program.findAddressOfLabel(_label);
                     address = mProgram.findAddressOfLabel(label);
                 }else{
                 }else{
                     _address = program.findAddressOfLabel(_label) - _instruction.getAddress();
                     address = mProgram.findAddressOfLabel(label) - instruction.getAddress();
                 }
                 }


                 _instruction.setLabelAddress(offsetAddress(_address, _instruction.getLabel()));
                 instruction.setLabelAddress(offsetAddress(address, instruction.getLabel()));
             }
             }
         }
         }
Linia 196: Linia 190:
}
}


//------------------------------------------------------------------------------
}
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------

Versiunea curentă din 4 noiembrie 2015 20:18

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 $