Tag Archives: exercise

Programming Methodologies, SS10
Mancala Spielfeld

Ziel des Spiels
Mancala ist ein besonders in Afrika, Asien und der Karibik weit verbreitetes Spiel. Meist werden Bohnen als Spielsteine verwendet, weshalb das Spiel auch als “Bohnenspiel” bekannt ist.
Ziel des Spiels ist es, möglichst viele Spielsteine in die eigene Sammelgrube zu befördern.

Spielaufbau
Das Spielfeld ist ein längliches Brett mit sechs Spielgruben auf jeder langen Seite. Links und rechts befindet sich je ein Vorratsloch für die gewonnenen Steine, die sog. Kalah. Zu Beginn des Spiels ist diese noch leer. In jeder Spielgrube 4 Steine liegen. Die eigene Kalah befindet sich vom Spieler aus gesehen auf der rechten Seite.

Spielbeginn und Ziehen
Gezogen wird abwechselnd und nach folgenden Regeln:
Der erste Spieler nimmt aus einer Spielgrube auf seiner Seite alle vier Steine und legt jeweils einen in die folgenden Gruben. Dabei geht er gegen den Uhrzeigersinn vor und wird eventuell auch in den Gruben des Gegners Steine ablegen. Die gegnerische Kalah wird ausgelassen. Der Gegner verfährt nun ebenso und verteilt alle Steine aus einer seiner Gruben. Man darf nochmal ziehen, wenn der letzte Stein eines Zuges in der eigenen Kalah landet.

Schlagen
Trifft einer der Spieler mit dem letzten Stein in der eigenen Hälfte auf eine leere Grube, darf er diese Steine und die des Gegners aus der gegenüberliegenden Grube nehmen und in seine Kalah legen. Auf der gegnerischen Seite muss mindestens ein Stein übrigbleiben, damit derjenige Spieler weiterspielen kann. In dem speziellen Fall, dass ein Spieler mit dem letzten Stein in der eigeenen Hälfte auf eine leere Grube trifft UND alle Gruben des Gegners bis auf die gegenüberliegenden Grube leer sind, dürfen keine Steine geklaut werden.

Spielende
Bleibt auf der gegenerischen Seite kein Stein übrig, darf der andere Spieler alle seine Steine in seine Kalah legen. Damit ist das Spiel beendet. Es werden nun die Steine gezählt, und wer die meisten hat, ist der Gewinner.

Online spielen könnt ihr z.B: hier (ACHTUNG: Das Spiel spiegelt nicht notwendigerweise unsere Interpretation der  Regeln wieder!!)

Compiler Construction, WS0910

This homework continues the Xtext exercise from homework #10. This time, you have to generate Java code from EngineeringC code. Add this example model to your EngineeringC project:


EngineeringCDiagram diag {
  ECBlockDecl test {
    ECStore x {
      value : "0"
    }

    ECStore y {
      value : "7"
    }

    ECComputeBlock comp1 {
      expression : "x = 6 * y"
    }
  }

  ECBlockDecl callTest {
    ECStore z {
      value : "0"
    }

    ECBlockAppl callTest {
      instanceof : test
    }

    ECComputeBlock comp2 {
      expression : "z = x + 42"
    }
  }
}

(Remember to first modify your grammar before creating a code generation template!)

The generated Java code should calculate the correct result for all ECComputeBlocks. To ensure this, create a JUnit test in the same package as the generated class. Call the generated methods from the test and ensure that the expected values are computed. To make cross-block variable access possible, you have to modify the Xpand template so that these variables are accessible from the generated methods.

Xtext Workflow from the lecture:

<workflow>
  <property file="workflow.properties"/>
  <component	class="org.eclipse.xtext.MweReader" uri="${modelFile}">
    <register class="de.unikassel.se.compilerbau.ECStandaloneSetup"/>
  </component>

  <component id="generator" class="org.eclipse.xpand2.Generator">
    <metaModel id="mm" class="org.eclipse.xtend.typesystem.emf.EmfMetaModel">
      <metaModelPackage value="de.unikassel.se.compilerbau.eC.ECPackage"/>
    </metaModel>
    <expand value="GenerateEC::Root FOR model"/>
    <outlet path="${srcGenPath}/">
      <postprocessor class="org.eclipse.xpand2.output.JavaBeautifier"/>
    </outlet>
  </component>
</workflow>

Helpful links:

Compiler Construction, WS0910

Please follow the instructions given in the lecture to complete the assignment.

* Download/install Xtext, preferably using a complete Eclipse distribution from http://xtext.itemis.com/xtext/language=en/23947/downloads
* Create a new workspace and a new Xtext project
* Write a grammar corresponding to the simplified EngineeringC model shown in the lecture
* Run the generated workflow and test the parser with some EngineeringC diagrams

To hand in your homework, ZIP the Eclipse workspace which contains the Xtext project and upload the ZIP file to your CVS repository. Deadline is Friday, Feb. 5th.

Compiler Construction, WS0910

Implement code generation for functions and function calls. You should test and implement the following features:

  • Generate a function from a funcDecl, using a separate InstructionList and adrTab.
  • Generate function calls, pushing actual parameters onto the stack and invoke a previously generated function by name.

You do not need to implement parameter overloading or access to global variables from functions.

Deadline is before the next lecture, which will be held Jan. 22nd. Until then, happy holidays everyone!

Compiler Construction, WS0910

Implement code generation for if, else and while statements. You should start by reenabling your interpreter unit tests and try to fix one by one by extending your code generator. The compiler should handle boolean operators <, >, =, <=, etc. The expression compiler should generate a branch instruction if it detects a conditional expression. Afterwards, the surrounding code handling the if statement is responsible for jump target fixup to implement branching logic. Please make sure to write tests for all if/else combinations with true and false conditions. while should be simpler, but make sure to test it, too.

Compiler Construction, WS0910

We’re now ready to actually generate working code. Your task, should you accept it, is to change your interpreter to a compiler for arithmetic expressions. Generate code for the following “features”:

  • Numbers (PUSH)
  • Addition / subtraction (DADD, DSUB)
  • Multiplication / division (DMUL, DDIV)
  • Variable assignment (DSTORE)
  • Variable access (DLOAD)
  • Edit: variable assignments do NOT have to work like expressions, i.e. you don’t have to support “x = y = 5”!

A common problem with code generation is that you have to distinguish between compile time and run time. These are two separate phases, which is different from the way most interpreters work. Compile time is the first phase, in which you parse statements and generate code. You can use the JVM debugger to check this phase for errors, have a look at the symbol table and the results of the parser. When running the generated code, you cannot simply attach a debugger to it. This means that in the case of a wrong result, you have to manually check the bytecode to see what’s wrong. You do not see that stack, you have no variable names and there are no explicit control structures. You can use the Navigator view in Eclipse to open the .class files in your bin folder and see the bytecode. To make sure the bytecode is working, manually interpret it in your head. Keep track of the values on the stack by writing them on a sheet of paper. Check out the BCEL manual for help on the bytecode!

And if anybody happens to know a good bytecode debugger, please let everyone know on the mailing list…

Compiler Construction, WS0910

We’ve made the jump from interpretation to actual compiling of expressions. To start your code-generating compiler, download the BCEL library from http://jakarta.apache.org/bcel/.

Add the library to your project build path and write an example Java program as shown in the lecture. Run the BCELifier tool that comes with the library and take a good look at the output. Refer to the BCEL manual to get a better understanding of the code. Now, modify your interpreter to initialize the bytecode generation facilities. Remove the call to your recursive interpreter. This will cause your tests to fail, so delete or ignore them for now. Write a simple test which evaluates a string which only contains a number. Include the code produced by BCELifier in your parser method. You can leave the hardcoded numerical value in the code. Check that a .class file is generated and load it using the Java ClassLoader, invoke the generated method using java.lang.reflect, and return the result produced by the generated code.

We will start to generate code from the input text in the next homework.

Compiler Construction, WS0910

Homework #4 (due Nov. 27th, see last entry!) requires you to implement the following:

  • extend the parser to handle if, else, and while statements. The new grammar rules are:
    ifStat ::= 'if' condExpr '{' block '}' ('else' '{' block '}')?
    whileStat ::= 'while' condExpr '{' block '}'
    condExpr ::= expr (bop expr)?
    bop ::= '<' | '>' | '==' | ...

    A conditional expression (condExpr) is true if its value is > 0, and false otherwise.

  • parse function declarations:
    funcDecl ::= name '(' paramDeclList ')' '{' block '}'
    paramDeclList ::= name*

    Extend your symbol table to be able to store a function declaration.

  • interpret function calls:
    factor ::= number | name | name '(' expr* ')'

    Make sure to handle parameter symbols correctly when calling functions. It should be possible to access globals from a function, but you may choose to make function execution free of side effects. Please make a comment or two about how your implementation works in the code!

Please remember to write simple test cases first (if without else, functions without parameters…). Develop iteratively, adding features as you go. Do not attempt to get everything right on first attempt…