<commit_before># Day 10: Simple Code Generation

In this lab, you develop a simple code generator, that generates Java bytecode from simple MiniJava programs, which only print integer constants in their main methods.

## Overview

### Objectives

1. Write a Jasmin program which prints `42`.
2. Implement a code generator that transforms MiniJava programs into Java bytecode.
The code generator should include
    1. A transformation from MiniJava ASTs to Jasmin ASTs which handles 
        * MiniJava programs 
        * with only a main class 
        * with a single print statement with
        * an integer constant expression.
    2. A menu action which invokes the transformation and pretty-prints the Jasmin AST to concrete syntax.
    3. A menu action which generates a Java class file instead of a Jasmin file.
    4. A menu action which runs the program (challenge).

### Submission

You need to submit your MiniJava project with a pull request against branch `assignment10` on GitHub. 
Your GitHub repository contains a step-by-step procedure how to file such a request. 
This project should contain a `README.md` with a short paragraph explaining the organisation of your Stratego files.

The deadline for submissions is December 10th, 17:59.

### Grading

You can earn up to 10 points for your Jasmin program and up to 75 points for your code generator:

* transformation (50 points)
    * program (2 points)
    * main class (18 points)
    * main method (13 points)
    * print statement (17 points)
* menu actions (10 points)
    * Jasmin (5 points)
    * Java class file (5 points)
* challenges (15 points)
    * target directories (4 points)
    * automatic code generation (5 points)
    * runner (6 points)

You can earn up to 5 points for the organisation of your Stratego files and up to 10 points for the quality of your code. We focus on readibility in general, meaningful variable names and the consistent use of Stratego paragdims. 
We will consider the fact that Stratego is new to you.

## Detailed Instructions

### Initial Editor Project

We provide you with an initial MiniJava project in the branch `assignment10`. 
Make sure you have this branch in your fork as well, before you start working on this assignment.

1. Import the project into your workspace:
    1. right-click into the Package Explorer
    2. select **Import...** from the context menu
    3. choose **General/Existing Projects into Workspace** from the list
    4. select the MiniJava project
    5. press the **Finish** button
2. Build the project:
    1. select the project folder
    2. select **Build Project** from the **Project** menu
    3. the console will report success or failure

This project contains the following implementations:

* MiniJava signatures in `common/src-gen/signatures/MiniJava-sig`.
* MiniJava pretty-printer in `common/src-gen/pp/MiniJava-pp`
* MiniJava syntactic completions in `common/src-gen/completions/MiniJava-esv`.
* MiniJava desugarings in `common/desugar`.
* MiniJava name analysis in `common/names`.
* MiniJava type analysis in `common/types`.
* JasminXT signatures in `common/src-gen/signatures/JasminXT*-sig`
* JasminXT pretty-printer in `common/src-gen/pp/JasminXT*-pp`

These implementations are already imported into the initial project.

### Write Jasmin Code

Consider the following simple MiniJava program:

    class Main {
        public static void main(String[] args) {
            System.out.println(42);
        }
    }

Write a Jasmin program `simple.j`, which you expect to be the result of a MiniJava-to-Jasmin compiler. 
Generate a Java class file from it and run it. 
Improve your program until it runs without errors.

### Integrate Code Generation into the Editor

Code generation should be a service of your MiniJava editor. To achieve this, define a new strategy `generate-jbc`, which will be associated with the *Generate Java bytecode* entry in the *Generate* menu. Implement this strategy in Stratego by following the interface for action strategies:

    generate-jbc: (selected, position, ast, path, project-path) -> (filename, result)

The implementation  should rely on a strategy `program-to-jbc`, which transforms MiniJava programs into Java bytecode. 

### Implement a Code Generation Strategy

Next, you need to implement `program-to-jbc`. 
You will do this stepwise over the remaining labs. 
During this lab, you should implement it for programs that contain only a main class, which prints a single integer constant. 
To understand Jasmin's abstract syntax, you can either
  study example ASTs generated by a Jasmin editor, 
  study the grammar in the Jasmin project, 
  or have a closer look into `src-gen/signatures/JasminXT-sig.str`.

1. Provide a rule for `exp-to-jbc`, which translates an integer constant from MiniJava into a sequence of Java bytecode instructions, that loads this constant to the operand stack. 
   Note that it is important to generate a sequence here, even if you only need a single instruction, because in general a MiniJava expression translates into a sequence of bytecode instructions.

2. Provide a rule for `stmt-to-jbc`, which translates a print statement from MiniJava into a sequence of Java bytecode instructions. 
This rule should call `exp-to-jbc` to translate the expression inside the print statement to a Java bytecode sequence. 

3. Provide a rule for `class-to-jbc`, which translates a main class from MiniJava into a Jasmin class file. 
This rule should call `stmt-to-jbc` to translate the statement inside the main method to a Java bytecode sequence.

4. Provide a rule for `program-to-jbc`, which translates a MiniJava program into a list of Jasmin class files. 
This rule should call `class-to-jbc` to translate the main class of the program into a Jasmin class file.

#### Testing

For testing purposes, you can define another menu entry which calls a strategy `to-jbc`, which dispatches to your different implementation rules:

    to-jbc = program-to-jbc + class-to-jbc + stmt-to-jbc + exp-to-jbc
    
This allows you to test your implementation by selecting a code fragment in the MiniJava editor and running your code generation builder.

#### Some Notes on Sequences

You can represent sequences as lists. 
Sequences of bytecode instructions are never nested. 
Thus, your generated sequences should also be flat lists. 
This requires you to compose sequences from recursive calls with surrounding instructions.
In general, there are four different approaches to this in Stratego:

1. Generate nested lists and flatten these lists afterwards by applying `flatten-list` (not recommended).

2. Compose lists with a head and tails notation. For example, `seq` might be a sequence generated by a recursive call. You can precede this sequence with instructions `instr1`, ..., `instrn` by writing `[ instr1, ..., instrn | seq ]`. 

3. Compose lists explicitly. 
    * `<conc> (l1, l2)` concatenates two lists `l1`and `l2`.
    * `<concat> [l1, ..., ln]` concatenates lists `l1` ... `ln`.  

4. Use special list variables (recommended). Stratego provides special variable names for sequences. These names end in `*`, for example `instr*`. When using such variables in a list, Stratego will inline the list elements at that position instead of creating a nested list. For example, 

        instr1* := [LDC(Int("1")), LDC(Int("2"))]; instr2* := [LDC("0"), instr1*, LDC("3")]

    is equivalent to

        instr1* := [LDC(Int("1")), LDC(Int("2"))]; instr2* := [LDC("0"), LDC("1"), LDC("2"), LDC("3")]

#### Generate Concrete Syntax

As you may have noticed, your implementation follows the code generation by transformation paradigm. The result of `to-jbc` is a Jasmin AST. Extend your builder strategy `generate-jbc` to generate concrete syntax. Therefor, you need to pretty-print the Jasmin ASTs, which are generated by `program-to-jbc`. You can find a pretty-printing strategy for Jasmin in `trans/jasmin.str`.

### Generate Java Class Files

At this point, you can generate Jasmin class files from simple MiniJava programs. To run your programs in the Java Virtual Machine, you need to generate Java class files.
Define a new builder *Generate Java class files* with corresponding builder strategy, that generates the Jasmin file and turns it into a Java class file. To generate the class file, you first need to generate the Jasmin AST.  

To translate a Jasmin AST into a Java class file, you can use the strategy `jasmin-generate` defined in `trans/jasmin.str`. This strategy will only work, if you specify the path of the source file in a Jasmin directive. 

### Notes on names in Jasmin

Even though in MiniJava some keywords are reserved, Jasmin has its own keywords. Some Jasmin implementations consider those as reserved, some do not. Typical examples are keywords such as `field` or `class`. In the Spoofax implementation, we do not reserve these, but other Jasmin implementations might do, particularly if they may not have the latest updates (Debian for example). See [StackOverflow](http://stackoverflow.com/questions/10371352/how-to-handle-field-named-as-keywords-in-jasmin) for more information about this.

## Challenges

Challenges are meant to distinguish excellent solutions from good solutions. Typically, they are less guided and require more investigation and programming skills.

### Target Directories

Real-world compilers like the JDT place generated code in designated directories, such as `bin/` or `src-gen/`. Implement a similar behaviour for your MiniJava compiler. Make sure you can handle classes with the same name from different programs and files with the same name from different directories.<commit_msg>Fixed small errors in assignment description day 10<commit_after># Day 10: Simple Code Generation

In this lab, you develop a simple code generator, that generates Java bytecode from simple MiniJava programs, which only print integer constants in their main methods.

## Overview

### Objectives

1. Write a Jasmin program which prints `42`.
2. Implement a code generator that transforms MiniJava programs into Java bytecode.
The code generator should include
    1. A transformation from MiniJava ASTs to Jasmin ASTs which handles 
        * MiniJava programs 
        * with only a main class 
        * with a single print statement with
        * an integer constant expression.
    2. A menu action which invokes the transformation and pretty-prints the Jasmin AST to concrete syntax.
    3. A menu action which generates a Java class file instead of a Jasmin file.
    4. A menu action which runs the program (challenge).

### Submission

You need to submit your MiniJava project with a pull request against branch `assignment10` on GitHub. 
Your GitHub repository contains a step-by-step procedure how to file such a request. 
This project should contain a `README.md` with a short paragraph explaining the organisation of your Stratego files.

The deadline for submissions is December 10th, 17:59.

### Grading

You can earn up to 10 points for your Jasmin program and up to 75 points for your code generator:

* transformation (50 points)
    * program (2 points)
    * main class (18 points)
    * main method (13 points)
    * print statement (17 points)
* menu actions (10 points)
    * Jasmin (5 points)
    * Java class file (5 points)
* challenges (15 points)
    * target directories (4 points)
    * automatic code generation (5 points)
    * runner (6 points)

You can earn up to 5 points for the organisation of your Stratego files and up to 10 points for the quality of your code. We focus on readibility in general, meaningful variable names and the consistent use of Stratego paragdims. 
We will consider the fact that Stratego is new to you.

## Detailed Instructions

### Initial Editor Project

We provide you with an initial MiniJava project in the branch `assignment10`. 
Make sure you have this branch in your fork as well, before you start working on this assignment.

1. Import the project into your workspace:
    1. right-click into the Package Explorer
    2. select **Import...** from the context menu
    3. choose **General/Existing Projects into Workspace** from the list
    4. select the MiniJava project
    5. press the **Finish** button
2. Build the project:
    1. select the project folder
    2. select **Build Project** from the **Project** menu
    3. the console will report success or failure

This project contains the following implementations:

* MiniJava signatures in `common/src-gen/signatures/MiniJava-sig`.
* MiniJava pretty-printer in `common/src-gen/pp/MiniJava-pp`
* MiniJava syntactic completions in `common/src-gen/completions/MiniJava-esv`.
* MiniJava desugarings in `common/desugar`.
* MiniJava name analysis in `common/names`.
* MiniJava type analysis in `common/types`.
* JasminXT signatures in `common/src-gen/signatures/JasminXT*-sig`
* JasminXT pretty-printer in `common/src-gen/pp/JasminXT*-pp`

These implementations are already imported into the initial project.

### Write Jasmin Code

Consider the following simple MiniJava program:

    class Main {
        public static void main(String[] args) {
            System.out.println(42);
        }
    }

Write a Jasmin program `simple.j`, which you expect to be the result of a MiniJava-to-Jasmin compiler. 
Generate a Java class file from it and run it. 
Improve your program until it runs without errors.

### Integrate Code Generation into the Editor

Code generation should be a service of your MiniJava editor. To achieve this, define a new strategy `generate-jbc`, which will be associated with the *Generate Java bytecode* entry in the *Generate* menu. Implement this strategy in Stratego by following the interface for action strategies:

    generate-jbc: (selected, position, ast, path, project-path) -> (filename, result)

The implementation  should rely on a strategy `program-to-jbc`, which transforms MiniJava programs into Java bytecode. 

### Implement a Code Generation Strategy

Next, you need to implement `program-to-jbc`. 
You will do this stepwise over the remaining labs. 
During this lab, you should implement it for programs that contain only a main class, which prints a single integer constant. 
To understand Jasmin's abstract syntax, you can either
  study example ASTs generated by a Jasmin editor, 
  study the grammar in the Jasmin project, 
  or have a closer look into `common/src-gen/signatures/JasminXT-sig.str`.

1. Provide a rule for `exp-to-jbc`, which translates an integer constant from MiniJava into a sequence of Java bytecode instructions, that loads this constant to the operand stack. 
   Note that it is important to generate a sequence here, even if you only need a single instruction, because in general a MiniJava expression translates into a sequence of bytecode instructions.

2. Provide a rule for `stmt-to-jbc`, which translates a print statement from MiniJava into a sequence of Java bytecode instructions. 
This rule should call `exp-to-jbc` to translate the expression inside the print statement to a Java bytecode sequence. 

3. Provide a rule for `class-to-jbc`, which translates a main class from MiniJava into a Jasmin class file. 
This rule should call `stmt-to-jbc` to translate the statement inside the main method to a Java bytecode sequence.

4. Provide a rule for `program-to-jbc`, which translates a MiniJava program into a list of Jasmin class files. 
This rule should call `class-to-jbc` to translate the main class of the program into a Jasmin class file.

#### Testing

For testing purposes, you can define another menu entry which calls a strategy `to-jbc`, which dispatches to your different implementation rules:

    to-jbc = program-to-jbc + class-to-jbc + stmt-to-jbc + exp-to-jbc
    
This allows you to test your implementation by selecting a code fragment in the MiniJava editor and running your code generation builder.

#### Some Notes on Sequences

You can represent sequences as lists. 
Sequences of bytecode instructions are never nested. 
Thus, your generated sequences should also be flat lists. 
This requires you to compose sequences from recursive calls with surrounding instructions.
In general, there are four different approaches to this in Stratego:

1. Generate nested lists and flatten these lists afterwards by applying `flatten-list` (not recommended).

2. Compose lists with a head and tails notation. For example, `seq` might be a sequence generated by a recursive call. You can precede this sequence with instructions `instr1`, ..., `instrn` by writing `[ instr1, ..., instrn | seq ]`. 

3. Compose lists explicitly. 
    * `<conc> (l1, l2)` concatenates two lists `l1`and `l2`.
    * `<concat> [l1, ..., ln]` concatenates lists `l1` ... `ln`.  

4. Use special list variables (recommended). Stratego provides special variable names for sequences. These names end in `*`, for example `instr*`. When using such variables in a list, Stratego will inline the list elements at that position instead of creating a nested list. For example, 

        instr1* := [LDC("1"), LDC("2")]; instr2* := [LDC("0"), instr1*, LDC("3")]

    is equivalent to

        instr1* := [LDC("1"), LDC("2")]; instr2* := [LDC("0"), LDC("1"), LDC("2"), LDC("3")]

#### Generate Concrete Syntax

As you may have noticed, your implementation follows the code generation by transformation paradigm. The result of `to-jbc` is a Jasmin AST. Extend your builder strategy `generate-jbc` to generate concrete syntax. Therefor, you need to pretty-print the Jasmin ASTs, which are generated by `program-to-jbc`. You can find a pretty-printing strategy for Jasmin in `trans/jasmin.str`.

### Generate Java Class Files

At this point, you can generate Jasmin class files from simple MiniJava programs. To run your programs in the Java Virtual Machine, you need to generate Java class files.
Define a new builder *Generate Java class files* with corresponding builder strategy, that generates the Jasmin file and turns it into a Java class file. To generate the class file, you first need to generate the Jasmin AST.  

To translate a Jasmin AST into a Java class file, you can use the strategy `jasmin-generate` defined in `trans/jasmin.str`. This strategy will only work, if you specify the path of the source file in a Jasmin directive. 

### Notes on names in Jasmin

Even though in MiniJava some keywords are reserved, Jasmin has its own keywords. Some Jasmin implementations consider those as reserved, some do not. Typical examples are keywords such as `field` or `class`. In the Spoofax implementation, we do not reserve these, but other Jasmin implementations might do, particularly if they may not have the latest updates (Debian for example). See [StackOverflow](http://stackoverflow.com/questions/10371352/how-to-handle-field-named-as-keywords-in-jasmin) for more information about this.

## Challenges

Challenges are meant to distinguish excellent solutions from good solutions. Typically, they are less guided and require more investigation and programming skills.

### Target Directories

Real-world compilers like the JDT place generated code in designated directories, such as `bin/` or `src-gen/`. Implement a similar behaviour for your MiniJava compiler. Make sure you can handle classes with the same name from different programs and files with the same name from different directories.
{'fraction_non_alphanumeric': 0.06628093196259752, 'fraction_numerical': 0.010022214186082554, 'mean_word_length': 4.021530479896239, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 9, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3800108', 'n_tokens_mistral': 5157, 'n_tokens_neox': 4926, 'n_words': 2702}