0% found this document useful (0 votes)
11 views13 pages

Part 4

This section discusses implementing a code generation phase for a language compiler. It covers generating code for memory allocation, functions, statements, expressions, and aggregate data member access. The deliverables include documentation on the analysis, design, implementation tools, and example generated assembly code.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
11 views13 pages

Part 4

This section discusses implementing a code generation phase for a language compiler. It covers generating code for memory allocation, functions, statements, expressions, and aggregate data member access. The deliverables include documentation on the analysis, design, implementation tools, and example generated assembly code.
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
You are on page 1/ 13

Part 4: Code Generation

This section covers implementing a code generation phase for the

language described in previous sections. Here's a breakdown of the

specific aspects for which code generation needs to be implemented:

Memory Allocation

Memory allocation happens as variables are declared. This space will

eventually store their values. Memory cells can be identified by:

A unique Moon assembly code label (global variables)

An offset relative to the stack frame where the variable resides during

its scope's execution (local variables)

The allocated memory size depends on the declared variable type

(integer, float, array, object, etc.). Here's a breakdown of memory


allocation for different data types:

Basic types (integer, float)

Arrays of basic types

Objects

Objects with inheritance

Objects with object members

Arrays of objects

Functions

Code for functions translates to Moon assembly code subroutines.

These are code blocks accessed by labels. When a function finishes,

control jumps back to the instruction following the initial jump.

Parameters are passed/received during the function call.

The return value is passed back to the calling function upon function

resolution.

To allow recursive function calls, a function call stack mechanism needs

to be implemented. This requires memory allocation for variables using

offsets relative to the current function's stack frame.

Member function calls should allow access to the data members of the

object from which they were called.


Here are specific aspects of function code generation:

Branching to a function's code block, executing it, and returning to the

calling function.

Branching to a previously called function.

Passing parameters as local values to the function.

Passing the return value back to the calling function upon function

resolution.

Function call stack mechanism and handling recursive function calls.

Calling member functions.

Calling deeply nested member functions.

Statements

Moon code needs to be implemented for every kind of statement

defined in the grammar, including:


Assignment statements

Conditional statements (if-else)

Loop statements (for, while)

Input/output statements (read, write)

Return statements

Here's a breakdown of code generation for specific statements:

Assignment statement: Correct assignment of the resulting expression

value to a variable, regardless of the expression type.

Conditional statement: Implement branching mechanisms for

conditional statements, including nested ones.

Loop statement: Implement branching mechanisms for loop

statements, including nested ones.

Input/output statement:

`read()`: Prompt the user for a value and assign it to the parameter

passed to the statement.

`write()`: Print the result of evaluating the expression passed as a

parameter to the Moon console.

Return statement: Pass the value of the expression passed to the


`return` statement back to the calling function.

Aggregate Data Member Access

Aggregate data types (arrays and objects) group data values. Code

needs to be generated to access these member values when used as

factors in expressions or the left-hand side of an assignment statement.

This includes accessing array elements and object members. Here are

specific scenarios:

Arrays of basic types (integer and float): Access single or

multidimensional array elements.

Arrays of objects: Access single or multidimensional array elements.

Objects:

Access members of basic types.

Access members of array types, as well as the array's elements.

Access members of object types, as well as the elements of this

object.

Access deeply nested objects.

Access the members of a superclass (for objects with inheritance).

Expressions
Code generation needs to handle computing the resulting value of an

entire expression. This ranges from simple cases (variable names or

literals) to complex expressions involving operators, array indexing

with expressions, and deeply nested object members. This involves:

Memory allocation for temporary results.

Register allocation/deallocation scheme.

Here's a breakdown of code generation for expressions:

Single variable or literal value.

Expressions involving all arithmetic, relational, and logical operators in

one expression.

Expressions involving an array factor whose indexes are themselves

expressions.

Expressions involving an object factor referring to deeply nested object

members.

Deliverables

Documentation
Analysis:

Description of the register allocation/deallocation scheme used.

Description of the memory usage scheme (tag-based, stack-based)

for temporary variables, function calls, data members, and calculation

of allocated memory for variables.

Description of the purpose of each phase involved in the code

generation. Mapping of semantic actions to AST nodes for each phase,

along with a description of the effect/role of each semantic action.

Design (continued):

Description/rationale of the overall solution structure and the roles

of the individual components used in the applied solution.

Implementation Tools:

Description of tools/libraries/techniques used in the

analysis/implementation.

Successful use of tools/libraries/techniques used in the


analysis/implementation.

Code:
The complete Moon assembler code generated for the input

program(s). This code should be able to be run by a Moon assembler

and/or virtual machine to produce the expected output.

Example Code Generation

Consider the following Moon program:

```moon

int x = 10;

float y = 3.14;

int arr[5] = {1, 2, 3, 4, 5};

void print_array(int arr[], int size) {

for (int i = 0; i < size; i++) {


write(arr[i]);

int main() {

print_array(arr, 5);

return 0;

```

The corresponding Moon assembly code for this program might look

like:

```assembly

; Global variables

x: .data 10 ; integer variable x

y: .data 3.14 ; float variable y

arr: .data 1 2 3 4 5 ; array arr

; Function print_array(int arr[], int size)

print_array:

push ebp ; save base pointer


mov ebp, esp ; set base pointer to stack pointer

; Local variables

mov [ebp-4], esi ; save size parameter

mov esi, [ebp+4] ; load size parameter

loop_begin:

push [ebp-8] ; push i (index) onto stack

mov eax, [ebp-8] ; load i (index)

mov [esp-4], eax ; store i (index) as array index

; arr[i]

mov eax, [esi+4*eax] ; load arr[i]

call write ; print arr[i]

dec [ebp-8] ; decrement i

cmp [ebp-8], 0 ; compare i to 0

jne loop_begin ; jump to loop_begin if i > 0

pop ebp ; restore base pointer

ret ; return from function


; Main function

main:

push ebp ; save base pointer

mov ebp, esp ; set base pointer to stack pointer

; Call print_array(arr, 5)

push 5 ; push size (5)

push arr ; push arr address

call print_array ; call print_array

mov eax, 0 ; set return value to 0

leave ; restore stack frame

ret ; return from main

; Write function (print a value to the console)

write:

push ebp ; save base pointer

mov ebp, esp ; set base pointer to stack pointer

; Load value to print from stack

mov eax, [esp+4] ; load value to print


; Print the value using system call

mov edi, 1 ; file descriptor for standard output (stdout)

mov esi, eax ; value to print

mov ecx, 1 ; number of bytes to print

syscall

pop ebp ; restore base pointer

ret ; return from function

```

This assembly code represents the translation of the Moon program

into low-level instructions that can be executed by a Moon virtual

machine. It handles memory allocation, function calls, expression

evaluation, and other aspects of code generation.

Conclusion

Code generation is a crucial phase in compiler construction,

transforming the high-level representation of a program (AST) into

machine-executable code. By implementing the described code

generation techniques, the Moon compiler can effectively translate

Moon programs into assembly code, enabling them to run on a Moon


virtual machine or interpreter.

You might also like