Java, Antler, and Assembly Project

Hi,I am looking to get this programming assignment done. It’s Java,

Antler, and assembly code. Everything needed to complete the assignment

is attached within this studypool question. If you need anything else

for the assignment please do let me know.

Assessed Exercise, Task 2: Semantic
analysis
Summary
In this task you are going to implement, in Java, a type checker for ASTs
for the same simple programming language. The input for this task is in the
form of an S-expression representing an AST, according to the
specification described for Task 1 of the coursework, read from System.in.
(We assume that the input program has passed the syntax analysis phase,
so you may assume that the S-expression is properly formatted.) The type
checker will do the checks (as detailed below) and print the appropriate
output to System.out.
To help you get up to speed, we provide a skeleton project which you can
use as a basis. However, you can write the type checker in any way you
like, as long as it adheres to the requirements specified below. Please note
that we require type errors to be reported through Java’s exception
handling mechanism, and according to a specific format (to facilitate
automated testing and feedback.) To help in this, we provide a custom
RuntimeException class (feel free to modify interfaces, arguments, etc.,
but please keep the generated output identical).
Once again, you will need a preprocessor (e.g., a lexer and a parser) to
turn the input AST (represented by an S-expression) into a data structure
that you can work on directly. To save your time, we also provide this as a
part of the skeleton project — however, as the input is now guaranteed to
be correctly formatted, and is in the form of an S-expression, it may now be
manageable to write one manually if you wish. In any case, please think
early and carefully about how you will implement pattern matching in your
code and make sure it works.
Please also carefully read the submission guidelines.
Function declarations and identifier scope
Functions may be declared in the top-level scope, in any order, and can
invoke functions which are defined earlier or later in the source file. (That
is: the order in which functions are declared, does not matter.) The
functions must have distinct names. We suggest that you use a symbol
table to maintain a record of the functions which have been declared, and
their types.
Any parameters taken by a function must have type either int or bool. In
type-checking a function declaration, it may be useful to define a separate
symbol table for the parameters of that function, and add the names of
those parameters together with their declared types. This type information
can then be used to type-check the function body. The body of the function
itself is a block, whose type must agree with the return type of the function.
We may summarise the rules about scope for identifiers as follows.

The definition of one function fnA, may involve the invocation of
another function fnB, which is declared either before or after the
function fnA.

No two functions may have the same name, and no two parameters
of the same function fnA may have the same name.

The parameters of a function fnA, may have the same name as some
function fnB.

A function parameter is only in-scope in the body of the declaration of
that function — there are no global variables or side-effects.

A function parameter must have type either int or bool.
Type deduction rules
The following are the rules which specify how expressions of various kinds
are to be typed.
Numerical expressions
Numerical expressions
Constants
Γ ⊢ ⟨IntLit⟩ : int
Γ ⊢ P : int
Γ ⊢ Q : int
Addition
Γ ⊢ (P + Q) : int
Γ ⊢ P : int
Γ ⊢ Q : int
Subtraction
Γ ⊢ (P – Q) : int
Γ ⊢ P : int
Γ ⊢ Q : int
Multiplication
Γ ⊢ (P * Q) : int
Γ ⊢ P : int
Γ ⊢ Q : int
Division
Γ ⊢ (P / Q) : int
These are expressions which take values of type int, in particular arising
from arithmetic operations on two values of type int. For any expression
involving an arithmetic operator as below, where one of the subexpressions involved is not of type int, should result in an error.
Comparisons
Comparison expressions
Γ ⊢ P : int
Γ ⊢ Q : int
Equality
Γ ⊢ (P == Q) : bool
Γ ⊢ P : int
Γ ⊢ Q : int
Less than
Γ ⊢ (P < Q) : bool Γ ⊢ P : int Γ ⊢ Q : int Greater than Γ ⊢ (P > Q) : bool
Less than
or equal
Greater than
or equal
Γ ⊢ P : int
Γ ⊢ Q : int
Γ ⊢ (P = Q) : bool
Comparison expressions are ones which relate two expressions of type int,
to produce an expression of type bool. For any expression involving a
comparison operator as below, where one of the sub-expressions involved
is not of type int, should result in an error.
Boolean operations
Boolean operators
Γ ⊢ P : bool
Γ ⊢ Q : bool
Logical AND
Γ ⊢ (P && Q) : bool
Γ ⊢ P : bool
Γ ⊢ Q : bool
Logical OR
Γ ⊢ (P || Q) : bool
Γ ⊢ P : bool
Γ ⊢ Q : bool
Logical XOR
Γ ⊢ (P ^^ Q) : bool
These are expressions which combine two values of type bool using a
logical operation, to produce another value of type bool. For any expression
involving a logical operator as below, where one of the sub-expressions
involved is not of type bool, should result in an error.
Statements
Statements
Skip statements
Γ ⊢ skip : unit
Γ ⊢ x : α
Γ ⊢ P : α
Assignments
Γ ⊢ x := P : unit
Γ ⊢ C : bool
Γ ⊢ B : unit
While loops
Γ ⊢ while C do {B} : unit
Γ ⊢ B : unit
Γ ⊢ C : bool
Repeat loops
Γ ⊢ repeat {B} until C : unit
These are ‘expressions’ which represent statements — not having an
interesting value (represented by assigning them the type unit). Any
statement such as those below, which involve a mismatch of types where
type-agreement is required, or which involve an expression other than
type bool where a boolean expression is expected, should result in an error.
Generic expressions
Generic expressions
Γ ⊢ subr : (α1 , … , αn) → β
Γ ⊢ E1 : α1

Γ ⊢ En : αn
Function
invocations
Γ ⊢ subr (E1, … , En) : β
Block
expressions
Γ ⊢ E1 : α1

Γ ⊢ En : αn
Γ ⊢ E1 ; … ; En : αn
Γ ⊢ C : bool
Γ ⊢ B1 : α
Γ ⊢ B2 : α
If statements
Γ ⊢ if C then {B1} else {B2} : α
These are expressions, whose types depend entirely on the types of other identifiers or expressions. In any case where there is a mismatch of types which are required to agree, or
where an expression other than type bool is found a boolean expression is expected, an error
should be returned.
Input/Output specification
Your type checker will read an AST, in the form of an S-expression, from System.in as
input. (The format will be the same as the output of the previous task, but may also contain
whitespace.) It will conduct the following checks (not necessarily in this order):
1. check that the program has a main function, which takes no arguments, and which has
return type int;
2. check that all functions have distinct names, and all of the parameters of each function
have distinct names;
3. check that all identifiers used in a function, are either the names of parameters of that
function, or the names of other functions which are defined somewhere;
4. Based on the type deduction rules above, type-check the function bodies contained in
the AST.
If any one of these conditions fail, your program will throw an instance of an Exception class
that we provide for this purpose, which will present diagnostic information in a standardised
format. If none of these errors are present, the input program will be printed
on System.out (again as an S-expression), but with the main function becoming the first
declared function.
We provide a skeleton project, for you to add code to, to help you to realise this Task. It
performs the work of reading the S-expression at the input, storing it in an abstract syntax
tree; it also contains the code necessary to verify the existence of a main procedure and to
produce output with this being the first declaration.
The specific requirements for the output of your code are as follows:

In the case where an exception is thrown, it should be caught by the main method in
your Java code, which should then invoke the report method of the exception.

In the case where the program is semantically valid, you do not have to use
whitespace in any specific way in the printed S-expression, but you may like to use
the Java class which we provide to pretty print these expressions (this is also included
in the skeleton project), for your own benefit/convenience.
Example #1
Consider the following input AST (as an S-expression).
[
[FunDecl,
Idfr(“fun”), IntType,
[[Idfr(“x”), IntType], [Idfr(“y”), IntType], [Idfr(“z”), IntType]],
[
[IfStmt,
[BinOpExpr, Eq, Idfr(“x”), Idfr(“y”)],
[
[BinOpExpr, Plus, Idfr(“z”),
[BinOpExpr, Eq, IntLit(1), IntLit(1)]
]
],
[IntLit(0)]
]
]
],
[FunDecl,
Idfr(“main”), IntType, [],
[
[FunInvoc,
Idfr(“fun”), [IntLit(1), IntLit(2), IntLit(3)]
]
]
],
[FunDecl,
Idfr(“fun2”), UnitType, [],
[ Skip ]
]
]
This is lexically and syntactically valid, but [BinOpExpr, Eq, IntLit(1), IntLit(1)] is
of type BoolType, and so is invalid as an operand of Plus. The type checker gives the
following output:
Invalid operands in arithmetic expression:
[BinOpExpr,
Plus,
Idfr(“z”),
[BinOpExpr,
Eq,
IntLit(1),
IntLit(1)]
]
and
[BinOpExpr,
Plus,
Idfr(“z”),
[BinOpExpr,
Eq,
IntLit(1),
IntLit(1)]]
–Idfr(“z”)
has type INT
,
[BinOpExpr,
Eq,
IntLit(1),
IntLit(1)]
has type BOOL
Example #2
Consider the following input AST (as an S-expression).
[
[FunDecl,
Idfr(“fun”), IntType,
[[Idfr(“x”), IntType], [Idfr(“y”), IntType], [Idfr(“z”), IntType]],
[
[WhileLoop,
[BinOpExpr, Eq, Idfr(“x”), Idfr(“y”)],
[
IntLit(1),
[BinOpExpr, Plus, IntLit(1), IntLit(3)],
Skip,
Idfr(“z”)
]
]
]
],
[FunDecl,
Idfr(“main”), IntType, [],
[
[FunInvoc,
Idfr(“fun”), [IntLit(1), IntLit(2), IntLit(3)]
]
]
],
[FunDecl,
Idfr(“fun2”), UnitType, [],
[Skip]
]
]
This is again lexically and syntactically valid, but the last expression Idfr(“z”) in the body
of the while loop is of type IntType, rather than UnitType as required by our typing rules.
The type checker gives the following output for the corresponding AST (S-expression):
Invalid final expression in loop body:
[WhileLoop,
[BinOpExpr,
Eq,
Idfr(“x”),
Idfr(“y”)],
[…,
…,
…,
Idfr(“z”)]
]
–Idfr(“z”)
has type INT
Do not worry about the formatting of / ANSI colour codes (which are used in the skeleton
project to decorate printed code) in the output – these are something which we can take care
of in the automated testing.
Resources
The skeleton project (extracted from a sample solution based on ANTLR); the main file that
needs to be modified is SExpressionsAnalyser.java. Please note that the skeleton project
is currently an incomplete implementation, and as such only one error will be detected and
reported, which is inadequate. To give you some hints, methods that require modification are
marked with TODO in comments. Some additional input/output samples can also be found in
the archive; you can run the input samples with the script run-tests.sh.
The custom RuntimeException class (this is also included in the skeleton project).
Coursework submission guidelines
Please, please, PLEASE read and follow the instructions below.
Make it possible for us to automatically compile
your code!
Make sure that all of the code that you submit can be compiled with a
single gradle build in the root project directory — this means that the
directory structure and the build
scripts settings.gradle and build.gradle must be configured properly (see
the explanations below and an example file here).

We will use Java 16 (more precisely Java compiler version “javac
16.0.2”) and Gradle 7.2. If you are planning to use features that are
not available in these versions, please contact us.

If you use an IDE such as IntelliJ IDEA, Eclipse, or BlueJ, please
make double sure that your source files are self-contained and
structured correctly — do not simply pack your IDE project directory!
— as some IDEs use different directory layouts/generate files with
dependencies that we cannot resolve. Please try building and
running your code with Gradle in an isolated directory (or potentially
another machine with a clean JDK installation) before submission.
Structuring your project
Please put your whole submission into a single directory that has your
candidate ID (i.e. a 6-digit string) as its name. This single directory
(called the root project in Gradle) has sub-directories task1, task2,
and task3 (called subprojects in Gradle).

Put settings.gradle (where task1, task2, and task3 are specified as
subprojects), and possibly other files shared among tasks, into the
root project directory. E.g., if you use ANTLR, you may also put its
pre-compiled .jar file here.

For each task, put the source files and a build
script build.gradle (where you may specify dependencies) into the
corresponding subproject directory.
If you use a lexer generator to produce a lexer, or a parser generator to
produce a parser, then please submit the inputs (e.g., grammar files) to the
generator(s) too. There is no need to integrate generators into your Gradle
build, however.
Make your code easy to assess
We will only run your code with Gradle. For example, to run your Task 2 we
will use the command gradle :task2:run in the root project directory (run is
defined in build.gradle in task2). To ensure that the tests run properly,
please do the following:

Make sure that your submission inputs from System.in.

Make sure that your submission outputs to System.out. In
particular, when we run your code, it should only output information
required by the task specification to System.out, with no redundant
messages such as those used for debugging.
Please try run-tests.sh in the example file to get an idea on how your code
will be tested.
Submitting your code
Please do the following when submitting your code for evaluation.

Please zip or tar.gz your submission (the root project directory that
has your candidate ID as its name). Submit only that archive as one
file. Do not use rar for submission:
rar cannot be reliably un-rar-ed on OSX and Linux. After you submit,
please download your submitted file and check that the archive can
be extracted.

For improved anonymity, and to improve the chances of your mark
being properly recorded, use your candidate ID as the submitted
filename, e.g., 234725.zip or 439231.tar.gz. Also, to ensure
anonymity, do not put your names anywhere in your submissions.
Originality and plagiarism
The work submitted must be your own. You may discuss the designs of
your programs with each other in broad outline, but discussions at the level
of program statements — or other forms of collaboration on actual code —
are unacceptable.
If you have not done so already, you would be well advised to consult the
University of Sussex Handbook guidelines on the subjects of collusion and
plagiarism: see here.
Assessed Exercise, Task 3: Code
Generation
Summary
In this task, you are going to implement a code generator targeting RISC-V
machine code, for ASTs for the same simple programming language.
The input for this task is again in the form of an S-expression representing
an AST, according to the specification described for Task 1, read
from System.in. For this task, we assume that the input program has passed
the both the syntax analysis phase (Task 1) and the semantic analysis phase
(Task 2).
The generated code, which is printed to System.out, should be valid and
executable RISC-V assembly code, with the result of the computation saved
in register a0 (also known as x10). For your convenience we provide the
simple assembler interface (based on RARS’s Java API) that we use to
verify your generated code.
You can make use of the grammar in the skeleton project provided for Task
2 to turn the input AST (represented by an S-expression) into a data structure
that you can work on directly (you will find symbol tables handy as you
generate code) — but again, you are free to write the code generator in any
way you want, as long as it adheres to the requirements specified below.
Please also carefully read the submission guidelines.
Input/Output specification
Input format
Your code generator will read an AST, in the form of an S-expression,
from System.in as input. (The format will be the same as the output of
the Task 1, but may also contain whitespace.) Note that the input is assumed
to satisfy the following:
1. The first function is main, which takes no arguments, and which has
return type int;
2. All functions have distinct names, and all parameters of each function
have distinct names;
3. All identifiers used in a function, are either the names of parameters
of that function, or the names of other functions which are defined
somewhere;
4. All the function bodies satisfy the type deduction rules of Task 2.
It will generate valid and executable RISC-V assembly code
that implements the input program — in particular, it is required that the
generated code can be simulated by RARS through the provided assembler
interface, which we use to verify your generated code.
Output format
After the generated code finishes execution, register a0 (also known as x10),
which is the second line of the output of RARSInterface.java, should be the
result of the computation (the return value of main). For example, if we
have rars_46ab74d.jar and RARSInterface.java in the current folder, we can
pipe RISC-V assembly code into RARS as follows (depending on your OS):

On *nix-based systems
We can pipe RISC-V assembly code into RARS with the shell
command
printf “li t0, 100\n\nmv a0, t0” | java -classpath
./rars_46ab74d.jar ./RARSInterface.java

On Windows systems
We can pipe RISC-V assembly code into RARS on the command line
using
cmd /c “(echo li t0, 100 & echo mv a0, t0) | java -classpath
.\rars_46ab74d.jar .\RARSInterface.java”
Additional technical remarks

The generated code should not lead to an error (such as memory
misalignment) or loop indefinitely while being simulated: the first line
of the output of RARSInterface.java should be
either CLIFF_TERMINATION or NORMAL_TERMINATION.

While the main function in the input program receives no argument,
we require that the generated code for all other functions to work
correctly for (sensible) arbitrary arguments. This means that a
suitable procedure call / return mechanism based on activation
records should be implemented in the generated code.

Integers should be mapped to RISC-V 32 bit signed integers, despite
the fact that we only allow non-negative integer literals in the input
language / S-expression. (You do not have to treat the possibility of
integer overflow / underflow.)
Some suggestions

It might be easier to first compile down to an intermediate
representation, such as stack machine code or register machine
code, and then embed the IR code into RISC-V assembly. We
provide an example assembly file that makes use of RARS’s macro
functionality to realise this idea. Note that it might be handy to
define some additional custom instructions!

Each new assembly command should be on a new line — i.e., don’t
put more than one assembly command on a line. Hint: Consider
generating a list of RISC-V assembly command strings, and then
concatenate them with added newlines after / between each.

You’ll need a function that generates fresh labels. Don’t hardcode
labels, ensure that the function generates a fresh label every time it is
called. Don’t use a random generator for this, use a global / static
variable for this purpose. This is one of the few legitimate uses of
global/static variables.

Check that your submission is not miscompiling conditionals
like if / then / else or loops in the sense that if the condition evaluates
to true then the else-branch is executed and vice versa.

You are advised against using global variables for function
parameters in your code generation methods; the reason is that
functions can be recursive, thus more than one activations of a single
function may be active at the same time.

We strongly recommend testing your code before submission. Note
that pasting code into RARS and simply press ‘Assemble’ is
insufficient as test, because that doesn’t test the termination of the
code generated by your code generator.
Resources
The simple assembler interface that we use to verify your generated code.
An example assembly file based on macros for stack machine instructions.
Assessed Exercise, Task 1: Lexer and
Parser
Summary
In this task you will write a lexer and a parser (or their combination, if
suitable) for this simple programming language. You are free to write these
in any way you want, whether ‘by hand’ or with software tools, as long as
they adhere to the requirements specified below (i.e. whether your lexer
and parser are two separate programs, or how you write them do not
matter for the mark).
We strongly recommend using generators (in particular ANTLR) as the
goal can be achieved with much less effort and hand-written code;
however, writing lexer or parser by hand will give you a better
understanding of the underlying technical details and difficulties.
Please also carefully read the submission guidelines.
Specification
In what follows, we assume the lexer and the parser are written separately.
Lexer specification
Your lexer will take an arbitrary string (over ASCII characters) as input, and
returns either a suitable token list when the input is lexically valid. The
tokens involved in the language are as follows:
Operator tokens
Token
Assign
Less
LessEq
Plus
Minus
And
Xor
Lexeme
:=
< >=
*
/
||
Token
Lexeme
Idfr
[a-z][A-Za-z0-9_]*
0 | [1-9][0-9]*
IntLit
Skip
skip
Type tokens
Token
IntType
BoolType
UnitType
Lexeme
int
bool
unit
Control flow tokens
Token
While
Do
Repeat
Until
Lexeme
Token
Lexeme
while
do
repeat
until
If
Then
Else
if
then
else
Delimiter tokens
Token
LParen
Comma
RParen
LBrace
Semicolon
RBrace
Lexeme
(
,
)
{
;
}
(The names of some of these tokens will be used as part of the output to
your program. We do most of the assessment using automated testing:
please use the same Tokens given here, for any output your code
produces!)
Your lexer will output a list of tokens, where the Idfr token and
the IntLit token store the additional information of the name of an
identifier or an integer value. (See the examples below.)
Parser specification
Your parser will take as input a token list, of the sort that your lexer
produces. When the input is syntactically valid, it should return an AST,
provided the input adheres to the syntax of the language.
The AST produced by your parser should be represented as an Sexpression. These are nested lists (whose elements may also be lists, and
so forth), representing sub-trees of the AST. Below, we describe the format
that we would like you to use for S-expressions — in particular, what we
will be looking for in the automated testing.
Implicit and explicit S-expressions
Each S-expression will have one of two formats: either

An explicit S-expression, whose first element is a ‘header label’.
These describes a specific syntactic structure with a specific number
of expected elements after the header; or

An implicit S-expression, consisting of a list of zero or more entries.
These may have any number of elements, but do not have a header,
so that their syntactical role must be determined from context.
We use ‘implicit’ S-expression only in a few places, where their meaning is
clear:
1. The very top level of the AST (representing a program as a sequence
of function declarations);
2. Block expressions (representing a block simply as a list of subexpressions);
3. Lists of function parameters or function arguments.
Every other part of the AST is represented by an ‘explicit’ S-expression —
except for parts of the language corresponding to ‘expression tokens’ as
above, which we represent simply with the very same tokens.
List of S-expression types
As noted above, the AST may contain some S-expressions with header
labels (describing their role in the AST), and some without. The header
labels are the following:
FunDecl
Asgmt
IfStmt
BinOpExpr
WhileLoop
FunInvoc
RepeatLoop
Apart from FunDecl, these all indicate different sorts of expressions.
The following are the types of S-expression, which we may use to
represent the different parts of an AST for the language above.

Top-level programs are represented by an implicit S-expression,
consisting simply of one or more function declarations:
[
(fun-decl-1) , (fun-decl-2) , … ]
These have no header, as no context is required to interpret the top
level of an AST in this language.

Function declarations are represented by an S-expression with a
“FunDecl” header, which specify an identifier token (fn-name-idfr) for
the function, a return type token (return-type), a list of parameters, and
a function body:
[FunDecl,
(fn-name-idfr), (return-type), [list of parameters], (fn-
body) ]
The list of parameters is provided as a list, of zero or more pairs,
where each pair consists of an identifier token (representing a
parameter name) and a type:
[ [(param-1-idfr),
(type-1)], [(param-2-idfr), (type-2)], … ]
The function body (fn-body) is given by an S-expression for
a BLOCK element, as described below.

Block expressions are represented by an S-expression without a
header, consisting simply of the list of one or more expressions in the
block:
[
(expr-1), (expr-2), … ]
Note that some of these expressions may themselves be blocks, in
which case they are also headerless S-expressions.

Assignment expressions are represented by an S-expression with
an “Asgmt” header, and two entries: an identifier (idfr) being assigned
to, and an expression (expr) which we are assigning to it.
[Asgmt,

(idfr), (expr) ]
Binary operator expressions are represented by an S-expression
with a “BinOpExpr” header, and three entries: a binary operator
token, and the two expressions involved in the operation.
[BinOpExpr,
(operator-token), (expr-1), (expr-2) ]

Function invocations are represented by an S-expression with a
“FunInvoc” header, and two entries: an identifier (idfr) representing
the function name, and a list of arguments to the function:
[FunInvoc,
(idfr), [list of arguments] ]
The list of arguments consists of a list of zero or more expressions
(similar to a block, but with a different meaning).

If-statements, while loops and repeat loops are represented with
similar S-expressions, respectively using headers “IfStmt”,
“WhileLoop”, and “RepeatLoop”, which have an expression
representing the condition of the loop or if-statement, and either one
block S-expression (for a loop body) or two block S-expressions (for
the then-body and the else-body of an if-statement).


[IfStmt,
[WhileLoop,
[RepeatLoop,
(expr), (then-body), (else-body) ]
(expr), (loop-body) ]
(expr), (loop-body) ]
Input/output specification
Your overall program is essentially the combination of the lexer and parser
described above:

it receives a string as input from System.in, using whitespace to
separate tokens but otherwise ignoring it;

it parses it, produces an AST, and prints it as an S-expression
to System.out.
We do not impose any constraints on what spaces or newlines your output
contains. However, we are happy to offer you a Java class to pretty print
these expressions, which may help you to debug your code. You might
wish to produce your S-expression as a String, provide this as input to the
pretty printer, and then produce the resulting string to System.out.
Note. For this task, you can assume all input to be lexically and
syntactically valid.
Examples
Here is a lexically and syntactically valid input.
int main() { fun(1, 2, 3) }
int fun(int x, int y, int z) { if (x == y) then { z } else { 0 } }
After lexing, it is turned into the following token stream. (You would
not print this as output.)
IntType,
Idfr(“fun”),
LParen,
IntLit(3),
RParen,
IntType,
Idfr(“x”),
IntType,
Idfr(“z”),
Idfr(“x”),
Eq,
Idfr(“z”),
RBrace,
RBrace
Idfr(“main”),
LParen,
RParen,
LBrace,
IntLit(1),
Comma,
IntLit(2),
Comma,
RBrace,
IntType,
Idfr(“fun”),
LParen,
Comma,
IntType,
Idfr(“y”),
Comma,
RParen,
LBrace,
If,
LParen,
Idfr(“y”),
RParen,
Then,
LBrace,
Else,
LBrace,
IntLit(0),
RBrace,
After parsing, we get the following S-expression (as formatted by the Java
class to pretty print these expressions), which we would print
to System.out:
[
[FunDecl,
Idfr(“main”),
IntType,
[],
[
[FunInvoc,
Idfr(“fun”),
[IntLit(1),
IntLit(2),
IntLit(3)]
]
]
],
[FunDecl,
Idfr(“fun”),
IntType,
[
[Idfr(“x”), IntType],
[Idfr(“y”), IntType],
[Idfr(“z”), IntType]
],
[
[IfStmt,
[BinOpExpr,
Eq,
Idfr(“x”),
Idfr(“y”)],
[Idfr(“z”)],
[IntLit(0)]
]
]
]
]
(Do not worry about the formatting — this is something which we can take
care of in the automated testing.)

Calculate your order
275 words
Total price: $0.00

Top-quality papers guaranteed

54

100% original papers

We sell only unique pieces of writing completed according to your demands.

54

Confidential service

We use security encryption to keep your personal data protected.

54

Money-back guarantee

We can give your money back if something goes wrong with your order.

Enjoy the free features we offer to everyone

  1. Title page

    Get a free title page formatted according to the specifics of your particular style.

  2. Custom formatting

    Request us to use APA, MLA, Harvard, Chicago, or any other style for your essay.

  3. Bibliography page

    Don’t pay extra for a list of references that perfectly fits your academic needs.

  4. 24/7 support assistance

    Ask us a question anytime you need to—we don’t charge extra for supporting you!

Calculate how much your essay costs

Type of paper
Academic level
Deadline
550 words

How to place an order

  • Choose the number of pages, your academic level, and deadline
  • Push the orange button
  • Give instructions for your paper
  • Pay with PayPal or a credit card
  • Track the progress of your order
  • Approve and enjoy your custom paper

Ask experts to write you a cheap essay of excellent quality

Place an order