Posts mit dem Label elegant code werden angezeigt. Alle Posts anzeigen
Posts mit dem Label elegant code werden angezeigt. Alle Posts anzeigen

Dienstag, 11. August 2015

Previsit a datastructure

Recently I had to write a small and relatively simple compiler and came across a problem. For the function prologue the stack pointer should be decreased by 4 * number of local variables. Compilers work with a datastructure so called "Abstract Syntax Tree". The important part is that it was realized with the Visitor design pattern. I was looking for a simple solution to know the number of local variables in the moment I want to decrease the stack pointer. I couldn't think of non-complex code and came across this elegant and simple solution:

Here we have the normal Visitor:
public interface ASTVisitor {

    public void visit(FunctionDefinitionExpression e);
    public void visit(DeclarationStatement s);
    // ...

}
All subtypes implement the accept method for the Visitor:
public class PrimaryExpression extends Expression {

    // ...
 
    @Override
    public void accept(ASTVisitor v) {
        v.visit(this);
    }

}
Here we have the implemention and the main logic:
public class ASTVisitorImpl implements ASTVisitor {

    @Override
    public void visit(FunctionDefinitionExpression e) {

        int n = 0;

        // here we will use our custom PreVisitor
        // and override our desired method
        funcDefinition.accept(new PreVisitor() {
         
            @Override
            public void visit(DeclarationStatement decl) {

                // add here your logic e.g.
                n++;
    
            }
         });

    }
}
That's our simple PreVisitor:
public class PreVisitor implements ASTVisitor {

    @Override
    public void visit(DeclarationStatement declarationStatement) {
    }

    @Override
    public void visit(BinaryExpression binaryExpression) {
        binaryExpression.elem1.accept(this);
        binaryExpression.elem2.accept(this);
    }

    // ...

}

So the solution was simply to create another subtype of the the same ASTVisitor interface and implement there all methods and just the logic to traverse the whole datastructure (Abstract Syntax Tree). At the moment you want to have a specific information without continuing at this point, you call the PreVisitor and override the desired method - et voilà you have an elegant solution!

Montag, 27. April 2015

HowTo#1 Avoid inflexible several if else statements/ switches

There are sometimes situations when you want to check an object and depending of the object you want a corresponding result, so you have some kind of mapping. Therefore you want to check the input if it is this or that etc. To be more specific let's consider the following situation:

void ProcessSomething(Color color) {

    FlowerType flowerType;

    if (color == Color.Red) {
        flowerType = Red_Rose;
    } else if (color == Color.Blue) {
        flowerType = Blue_Rose;
    } else if (color == Color.Grey) {
        flowerType = Grey_Rose;
    } else if (color == Color.Yellow) {
        flowerType = Yellow_Rose;
    }  

    // Do something
}

Obviously this is a bad style and leads to inflexible code, but what is the alternative? You could use a switch statement, but this wouldn't lead to a more elegant code.
If you have some kind of mapping for example between Enums, you can do the following:

// Java
public static enum Color {
    Red, Blue, Grey, Yellow;

    private static EnumMap map = new EnumMap(Color.class);

    static {
        map.put(Color.Red, FlowerType.Red_Rose);
        map.put(Color.Blue, FlowerType.Blue_Rose);
        map.put(Color.Grey, FlowerType.Grey_Rose);
        map.put(Color.Yellow, FlowerType.Yellow_Rose);
    }

    public static FlowerType getCorrespondigValue(Color value) {
        return map.get(value);
    }
}
// Apparently there is a bug with the syntaxhighlighter
// In line 5 the correct version is "FlowerType"
// And it adds  in the end, probably it has a problem with "<"

In the case of Enums we can use an EnumMap and use a static block to map the corresponding types. As a result we have a neverchanging and flexible static getCorrespondigValue method, which returns reliably the FlowerType. If you don't use Enums you can use instead of EnumMap a HashMap.


Here is an extract from my Pokemon game in C++ Unreal Engine:
// C++
static TMap MapNameEItemEnum;

UENUM(BlueprintType)
enum class EItemEnum : uint8
{
    Potion                 UMETA(DisplayName = "Potion"),
    Pokeball             UMETA(DisplayName = "Pokeball"),
    Superball            UMETA(DisplayName = "Superball"),
    None                UMETA(DisplayName = "None")
};

static void init()
{
    MapNameEItemEnum.Add(FString(TEXT("Potion")), EItemEnum::Potion);
    MapNameEItemEnum.Add(FString(TEXT("Pokeball")), EItemEnum::Pokeball);
    MapNameEItemEnum.Add(FString(TEXT("Superball")), EItemEnum::Superball);
    MapNameEItemEnum.Add(FString(TEXT("None")), EItemEnum::None);
}


EItemEnum GetCorrespondingStringAsEItemEnum(const FString Str)
{
    EItemEnum* Item = MapNameEItemEnum.Find(Str);

    if (Item)
        return *Item;
    else
        return EItemEnum::None;
}
// Again a bug with the syntaxhighlighter in line 2
// "FString, EItemEnum" is the correct version

Of course you can use the same concept in normal C++, if you don't work with Unreal Engine. Note that there are no simple static blocks in C++ like in Java.