Homework 4
This commit is contained in:
parent
0afc86ceeb
commit
72cc3206c4
125 changed files with 4208 additions and 1644 deletions
|
|
@ -2,10 +2,10 @@
|
|||
<classpath>
|
||||
<classpathentry kind="src" path="src"/>
|
||||
<classpathentry kind="src" path="test"/>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
|
||||
<classpathentry kind="lib" path="lib/antlr-4.4-complete.jar"/>
|
||||
<classpathentry kind="lib" path="lib/junit-4.12.jar"/>
|
||||
<classpathentry kind="lib" path="lib/hamcrest-core-1.3.jar"/>
|
||||
<classpathentry kind="lib" path="lib/antlr-4.7.1-complete.jar"/>
|
||||
<classpathentry kind="lib" path="lib/javaliParserObf.jar"/>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
|
||||
<classpathentry kind="output" path="bin"/>
|
||||
</classpath>
|
||||
|
|
|
|||
2
.project
2
.project
|
|
@ -1,6 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>Javali-HW3</name>
|
||||
<name>Javali-HW4</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
||||
|
|
|
|||
|
|
@ -1,2 +0,0 @@
|
|||
eclipse.preferences.version=1
|
||||
encoding/<project>=UTF-8
|
||||
39
Grade.txt
39
Grade.txt
|
|
@ -1,6 +1,39 @@
|
|||
Grade: 25/25
|
||||
nop90: 29/30 points
|
||||
|
||||
105/105 tests passed [20/20]
|
||||
Comments:
|
||||
I found that the following tasks were not implemented correctly or contained errors.
|
||||
|
||||
Submitted test cases: [5/5]
|
||||
* Null pointers check doesn't work for methods:
|
||||
"
|
||||
class Main {
|
||||
void main() {
|
||||
A a;
|
||||
a.m();
|
||||
}
|
||||
}
|
||||
class A {
|
||||
void m() { }
|
||||
}
|
||||
"
|
||||
* Side effects
|
||||
If methods have side effects, then the execution order matters:
|
||||
"
|
||||
class Main {
|
||||
void main() {
|
||||
write(m1() + m2());
|
||||
writeln();
|
||||
}
|
||||
|
||||
int m1() {
|
||||
write(1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int m2() {
|
||||
write(2);
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
"
|
||||
* Can't compile programs which use many registers
|
||||
|
||||
|
|
|
|||
144
README.md
144
README.md
|
|
@ -1,55 +1,111 @@
|
|||
# Compiler design
|
||||
## Parser and syntactic analysis
|
||||
See repo containing [Homework #2](https://svn.inf.ethz.ch/svn/trg/cd_students/ss18/teams/nop90/HW2).
|
||||
# HW4: code generation
|
||||
Better viewed as markdown
|
||||
|
||||
## Semantic analysis
|
||||
This project checks a list class declaration as trees of Ast nodes for
|
||||
possible semantic errors.
|
||||
# VTables
|
||||
They are generated when each class is visited, except for those of Object,
|
||||
Object[], int[] and boolean[], which are generated in the bootstrapping.
|
||||
|
||||
### Design
|
||||
The semantic checks described [here](./SemanticChecks.md) are implemented in three
|
||||
phases.
|
||||
When the object vtable is generated, so is the array table, which just
|
||||
contains a reference to the supertype (in our case `Object`) and an unused
|
||||
pointer to the declared type of the element's vtable.
|
||||
|
||||
1. Circular inheritance check (just with the names, and checking for non-existent
|
||||
types) to avoid stack overflow problems in the main analysis. May throw a
|
||||
`NO_SUCH_TYPE` error if the parent of a given class doesn't exist.
|
||||
2. Main semantic analysis, performed by `StmtAnalyzer` and `ExprAnalyzer`,
|
||||
two visitors that traverse each `ClassDecl` and all of its contents looking
|
||||
for semantic errors. Some types and methods may not have been discovered
|
||||
when they are accessed, and to that end the functions `findType(String)`
|
||||
and `findMethod(String,ClassSymbol)` lookup both, searching unvisited class
|
||||
and method declarations in order to find the corresponding symbol.
|
||||
3. Lookup of start point (method `void main()` in `Main` class)
|
||||
supertype pointer (Object) <-- vtable pointer
|
||||
element vtable pointer (unused)
|
||||
|
||||
### Testing
|
||||
A set of test cases (Javali programs, valid and invalid) are provided. The ones
|
||||
designed specifically for this homework assignment are located in
|
||||
`javali_tests/HW3_nop90`, and they cover all the code in the `cd.frontend.semantic`
|
||||
and `cd.ir` packages. They cover all the kinds of errors that can arise
|
||||
from a semantic analysis of Javali programs. As the order of the errors
|
||||
is not determined, each test case only checks one failing condition, and
|
||||
therefore many more test cases are needed for this homework than for
|
||||
previous ones.
|
||||
Each type's vtable contains the supertype as the first element (trait shared
|
||||
with array type's vtables for easier cast type comparisons). Then they
|
||||
contain all the methods available to an object of that type, including
|
||||
all those inherited. As the dynamic type is not known, the number and
|
||||
position of the methods is not known when executing a method, therefore
|
||||
each method's pointer is prepended by the method's name hash (similar to
|
||||
fields in an object).
|
||||
|
||||
The test files are organized in folders, with names ending in Tests or Errors,
|
||||
the latter only contain test cases that result in semantic errors.
|
||||
supertype pointer <-- vtable pointer
|
||||
hash("method0")
|
||||
method0 pointer
|
||||
hash("method1")
|
||||
method1 pointer
|
||||
...
|
||||
hash("methodN")
|
||||
methodN pointer
|
||||
|
||||
To run the tests that exist in the `javali_tests` folder you can simply run
|
||||
# Method calls
|
||||
|
||||
$ ant clean clean-test compile test
|
||||
The basic scheme used for method calls and the structure of the stack
|
||||
frame is that described in the `__cdecl` used in GCC. In short, this is
|
||||
the execution of a method call:
|
||||
|
||||
### Development environment
|
||||
This project is designed for Eclipse and GNU/Linux, but it can be run
|
||||
in other environments, as long as they have a 32bit `IA 86x assembly` compiler
|
||||
and a `JVM`. Check the `Config` class for more information.
|
||||
1. The caller pushes the arguments in the stack, from right-to-left,
|
||||
leaving the 0th argument (the reference to `this`) at the top of the stack.
|
||||
2. The caller executes `call` (the instruction pointer gets stored in the stack)
|
||||
3. The callee now takes control, and its first action is to save the base
|
||||
pointer to the stack and set the base pointer to the current stack pointer.
|
||||
Therefore, the arguments and return address are available to the method.
|
||||
4. The local variables are reserved and zeroed in the stack.
|
||||
5. The CALLEE_SAVED registers are saved to the stack.
|
||||
6. The method executes its code
|
||||
7. The CALLEE_SAVED registers are restored to their original status.
|
||||
8. The callee restores the stack and base registers to its initial statuses.
|
||||
This is accomplished with a `leave` instruction. Then it returns using `ret`.
|
||||
This removes the instruction pointer from the stack leaving only the arguments.
|
||||
9. The caller finally removes all the arguments from the stack and obtains the
|
||||
return value from EAX.
|
||||
|
||||
### Documentation
|
||||
Available as [javadoc](javadoc/index.html). It is generated running the following command:
|
||||
Therefore, the stack frame follows the following structure (N arguments
|
||||
and M local variables):
|
||||
|
||||
$ ant clean-doc generate-doc
|
||||
top of stack <-- ESP
|
||||
...
|
||||
saved registers
|
||||
localM <-- EBP - 4 - M * 4
|
||||
...
|
||||
local1 <-- EBP - 8
|
||||
local0 <-- EBP - 4
|
||||
Old EBP <-- EBP
|
||||
Return EIP
|
||||
this <-- EBP + 8
|
||||
arg0 <-- EBP + 12
|
||||
...
|
||||
argN <-- EBP + 12 + N * 4
|
||||
|
||||
### Important files
|
||||
* `TODO.md`: contains tasks to complete
|
||||
* `SemanticChecks.md`: contains the semantic checks numbered for quick reference
|
||||
* [Javali Grammar](https://www.ethz.ch/content/dam/ethz/special-interest/infk/inst-cs/lst-dam/documents/Education/Classes/Spring2018/210_Compiler_Design/Homework/javali.pdf)
|
||||
* [HW3 statement](https://www.ethz.ch/content/dam/ethz/special-interest/infk/inst-cs/lst-dam/documents/Education/Classes/Spring2018/210_Compiler_Design/Homework/hw3.pdf)
|
||||
# Variable and object representation
|
||||
## Primitive variables
|
||||
They are represented by value, with both integers and booleans occupying
|
||||
4 bytes, and booleans being represented as TRUE = 0, FALSE = 1.
|
||||
|
||||
## Reference variables
|
||||
Stored in the heap, using calloc (to zero-initialize them).
|
||||
|
||||
### Arrays
|
||||
On top of storing the array elements, some overhead is stored with it,
|
||||
namely a pointer to the array vtable for casts, and the size of the
|
||||
array to check the bounds of the array on accesses or assignments.
|
||||
The pointer to the array points to the vtable pointer (the first
|
||||
element in the object structure):
|
||||
|
||||
array vtable pointer <-- var pointer
|
||||
array size
|
||||
element0
|
||||
element1
|
||||
...
|
||||
elementN
|
||||
|
||||
### Objects
|
||||
|
||||
Stores a pointer to the object's type vtable and all the fields. As the
|
||||
dynamic type of the object cannot be determined and therefore the fields
|
||||
not statically ordered, each field occupies 8 bytes, with the first 4 containing
|
||||
the hash for the VariableSymbol that represents it and the others the
|
||||
value or reference to the field.
|
||||
|
||||
The hash allows hiding variables, but introduces an overhead when accessing
|
||||
a field, to look for the position in which it is located.
|
||||
|
||||
vtable pointer <-- var pointer
|
||||
field0's hash
|
||||
field0
|
||||
field1's hash
|
||||
field1
|
||||
...
|
||||
fieldN's hash
|
||||
fieldN
|
||||
|
|
|
|||
|
|
@ -1,43 +0,0 @@
|
|||
# Class and method declaration errors
|
||||
1. All programs must have a method main() with void return type in the class Main (`INVALID_START_POINT`)
|
||||
2. The superclass of each class exists (`NO_SUCH_TYPE`)
|
||||
3. There is no circular inheritance (`CIRCULAR_INHERITANCE`)
|
||||
4. No class is declared with the name `Object` (`OBJECT_CLASS_DEFINED`)
|
||||
5. Unique names (`DOUBLE_DECLARATION`) for each group:
|
||||
1. Class names
|
||||
2. Field names in a single class (field shadowing is allowed)
|
||||
3. Method names in a single class (Override is allowed, overloading not)
|
||||
4. Method parameters and local variable names
|
||||
6. Overridden methods must: (`INVALID_OVERRIDE`)
|
||||
1. Have the same number of parameters
|
||||
2. The return types must match
|
||||
3. The type of the parameters must match (name can differ)
|
||||
|
||||
# Method body errors
|
||||
1. `write()` must take one argument of type `int` (`TYPE_ERROR`)
|
||||
2. `read()` and `writeln()` must take no arguments (`WRONG_NUMBER_OF_ARGUMENTS`)
|
||||
3. The condition of a `while` or `if` statement must be typed `booelan` (`TYPE_ERROR`)
|
||||
4. Assignments: the type of the right-hand side must be a suptype of the type of the left-hand side. (`TYPE_ERROR`)
|
||||
5. Operators (`TYPE_ERROR`):
|
||||
1. `*`, `/`, `%`, `+`, `-`, `<`, `>`, `<=`, `>=` take `int` arguments only.
|
||||
2. `!`, `&&`, `||` take `boolean` arguments only.
|
||||
3. `==` and `!=` takes any couple of arguments as long as one of the types is a subtype of the other.
|
||||
4. A cast is only possible if one of the types is a subtype of the other
|
||||
6. Method invocation, must match with declaration:
|
||||
1. The number of parameters (`WRONG_NUMBER_OF_ARGUMENTS`)
|
||||
2. The type of each of the parameters (`TYPE_ERROR`)
|
||||
7. Arrays:
|
||||
1. When indexing, the index expression must be an `int` (`TYPE_ERROR`)
|
||||
2. When creating one, the index expression must be an `int` (`TYPE_ERROR`)
|
||||
8. The constant `null` can be assigned to any reference type.
|
||||
9. The type name in a `new` statement must exist (`NO_SUCH_TYPE`)
|
||||
10. The left-hand side of an assignment can only be: (`NOT_ASSIGNABLE`)
|
||||
1. A variable
|
||||
2. A field
|
||||
3. Array dereferences (indexing)
|
||||
11. There must be no attempt to access the field or method of a
|
||||
non-object type, such as arrays or primitive types (`TYPE_ERROR`)
|
||||
12. A method with a return type must have a return statement at the end
|
||||
of all its paths (`MISSING_RETURN`). A while loop is not a valid return
|
||||
regardless of the condition. A ifElse must have a return on both the
|
||||
else and otherwise block. There may be some statements after a return.
|
||||
75
TODO.md
75
TODO.md
|
|
@ -1,75 +0,0 @@
|
|||
## Possible code changes
|
||||
### General
|
||||
* DONE Use more specific messages when throwing a `SemanticFailure` exception. This has the caveat that the automated testing relies on those tests?
|
||||
|
||||
### StmtAnalyzer
|
||||
* DONE Propagate the change of class parameter from `ExprAnalyzer`.
|
||||
* DONE Complete checks for `MISSING_RETURN`, some ideas:
|
||||
* DONE Assume no instructions will appear after a return statement and analyze only the last `Stmt` using other visitor
|
||||
with different class parameters (for example passing the desired type and returning a `Optional<TypeSymbol>`).
|
||||
* DONE Decide the logic behind a return statement in a `while` loop, maybe treat it as an `if` with an empty `else` block.
|
||||
* A `while` as last instruction is not a valid return.
|
||||
* A `if` as last instruction must have a valid return a the end of its then and otherwise blocks.
|
||||
|
||||
### ExprAnalyzer
|
||||
* DONE Change the second class parameter to give method AND class information (needed by var and this nodes)
|
||||
* DISCARDED Add a ClassSymbol to MethodSymbol and use it as class parameter, the problem arises when visiting a method,
|
||||
should an empty method with the proper class be provided? Could also be solved by using `Symbol` as class parameter.
|
||||
* DONE Create a new class that includes a `ClassSymbol` and a `MethodSymbol` and use that. Keep `MethodSymbol == null`
|
||||
when appropriate.
|
||||
|
||||
## Tests
|
||||
This tests have been selected to increase to 100% the code coverage obtained by running the tests designed for the previous HW,
|
||||
which are in folder svn/HW2/javali_tests/HW2_nop90
|
||||
|
||||
As they are mostly related to errors that haven't been triggered, each test should be separate, in order to generate all
|
||||
of the errors.
|
||||
|
||||
### Remaining
|
||||
### Done
|
||||
* access var from class or superclass
|
||||
* test ! operator
|
||||
* type error in unaryOp
|
||||
* type error in array size
|
||||
* call method from superclass
|
||||
* call a method that doesn't exist
|
||||
* call a method with the wrong type of params
|
||||
* call a method with the wrong number of params
|
||||
* assign to all possible syntactically correct options
|
||||
* field
|
||||
* var
|
||||
* array index
|
||||
* method (error)
|
||||
* this (error)
|
||||
* indexing both types error
|
||||
* try to access a field of something that is not a class type
|
||||
* typing error in cast
|
||||
* AND and OR operations
|
||||
* equals operators (a case that is OK and another that's not)
|
||||
* binary operation with wrong type (any but == and !=)
|
||||
* search for a type that doesn't exist in a method body
|
||||
* don't have a Main class
|
||||
* don't have a main() method in the Main class (all possibilities)
|
||||
* wrong name
|
||||
* wrong return value
|
||||
* wrong parameters
|
||||
* inherited main method (it should work)
|
||||
* write something that is not an integer
|
||||
* declare a variable mutiple times (local variables)
|
||||
* declare a local variable with the same name as a parameter
|
||||
* check MISSING_RETURN
|
||||
* nested ifElse as end of method
|
||||
* while as end of method
|
||||
* normal returns at the end of the method
|
||||
* return with further statements after it
|
||||
* while with non-int condition
|
||||
* use a array type that hasn't been discovered yet
|
||||
* ```class A { B[] name; } class B {}```
|
||||
* name a class Object
|
||||
* name a class like another class
|
||||
* name a parameter like another
|
||||
* override methods and try to break that
|
||||
* same return type
|
||||
* same number of params
|
||||
* same type of params
|
||||
* name a variable like another (field level)
|
||||
107
build.xml
107
build.xml
|
|
@ -15,31 +15,26 @@
|
|||
<property name="antlr.jar" value="${basedir}/lib/antlr-4.4-complete.jar"/>
|
||||
<property name="antlr.profile" value="false"/>
|
||||
<property name="antlr.report" value="false"/>
|
||||
<property name="jacocoant.jar" value="${basedir}/lib/jacocoant.jar"/>
|
||||
<property name="coverage.file" location="${build.dir}/jacoco.exec"/>
|
||||
<property name="min.coverage" value="0.5"/>
|
||||
<property name="coverage.check" value="cd.frontend.*:cd.backend.*"/>
|
||||
<property name="doc.dir" value="javadoc"/>
|
||||
|
||||
<!-- Cleans generated code, but NOT the parser source! -->
|
||||
<target name="clean">
|
||||
<delete dir="${build.dir}"/>
|
||||
</target>
|
||||
|
||||
<target name="compile">
|
||||
<mkdir dir="${build.dir}"/>
|
||||
<target name="compile">
|
||||
<mkdir dir="${build.dir}"/>
|
||||
|
||||
<javac debug="true" destdir="${build.dir}" includeantruntime="false">
|
||||
<src path="${src.dir}"/>
|
||||
<src path="${test.dir}"/>
|
||||
<classpath>
|
||||
<pathelement location="${antlr.jar}"/>
|
||||
<pathelement location="${junit.jar}"/>
|
||||
<pathelement location="${hamcrest.jar}"/>
|
||||
<pathelement location="${parser.jar}"/>
|
||||
</classpath>
|
||||
</javac>
|
||||
</target>
|
||||
<javac debug="true" destdir="${build.dir}" includeantruntime="false">
|
||||
<src path="${src.dir}"/>
|
||||
<src path="${test.dir}"/>
|
||||
<classpath>
|
||||
<pathelement location="${antlr.jar}"/>
|
||||
<pathelement location="${junit.jar}"/>
|
||||
<pathelement location="${hamcrest.jar}"/>
|
||||
<pathelement location="${parser.jar}"/>
|
||||
</classpath>
|
||||
</javac>
|
||||
</target>
|
||||
|
||||
<!-- Deletes all byproducts of running the tests -->
|
||||
<target name="clean-test">
|
||||
|
|
@ -49,70 +44,28 @@
|
|||
<fileset dir="${javali_tests.dir}" includes="**/*.bin"/>
|
||||
<fileset dir="${javali_tests.dir}" includes="**/*.dot"/>
|
||||
<fileset dir="${javali_tests.dir}" includes="**/*.exe"/>
|
||||
<fileset dir="${javali_tests.dir}" includes="**/*.ref"/>
|
||||
<fileset dir="${javali_tests.dir}" includes="**/*.ref"/>
|
||||
</delete>
|
||||
</target>
|
||||
|
||||
<taskdef uri="antlib:org.jacoco.ant" resource="org/jacoco/ant/antlib.xml">
|
||||
<classpath path="${jacocoant.jar}"/>
|
||||
</taskdef>
|
||||
|
||||
<!-- Runs the tests. Use the compile target first! -->
|
||||
<target name="test" depends="compile">
|
||||
<jacoco:coverage destfile="${coverage.file}">
|
||||
<junit fork="true" forkmode="once" failureproperty="tests-failed" outputtoformatters="false">
|
||||
<formatter type="brief" usefile="false"/>
|
||||
<batchtest skipNonTests="true">
|
||||
<fileset dir="bin" includes="**/*.class" />
|
||||
</batchtest>
|
||||
<assertions enablesystemassertions="true" />
|
||||
<sysproperty key="cd.meta_hidden.Version" value="REFERENCE" />
|
||||
<classpath>
|
||||
<pathelement location="${build.dir}"/>
|
||||
<pathelement location="${junit.jar}"/>
|
||||
<pathelement location="${hamcrest.jar}"/>
|
||||
<pathelement location="${antlr.jar}"/>
|
||||
<pathelement location="${parser.jar}"/>
|
||||
</classpath>
|
||||
</junit>
|
||||
</jacoco:coverage>
|
||||
<fail if="tests-failed" />
|
||||
<junit fork="true" forkmode="once" failureproperty="tests-failed" outputtoformatters="false">
|
||||
<formatter type="brief" usefile="false"/>
|
||||
<batchtest skipNonTests="true">
|
||||
<fileset dir="bin" includes="**/*.class" />
|
||||
</batchtest>
|
||||
<assertions enablesystemassertions="true" />
|
||||
<sysproperty key="cd.meta_hidden.Version" value="REFERENCE" />
|
||||
<classpath>
|
||||
<pathelement location="${build.dir}"/>
|
||||
<pathelement location="${junit.jar}"/>
|
||||
<pathelement location="${hamcrest.jar}"/>
|
||||
<pathelement location="${antlr.jar}"/>
|
||||
<pathelement location="${parser.jar}"/>
|
||||
</classpath>
|
||||
</junit>
|
||||
<fail if="tests-failed" />
|
||||
</target>
|
||||
|
||||
<target name="test-coverage-report">
|
||||
<jacoco:report>
|
||||
<executiondata>
|
||||
<file file="${coverage.file}"/>
|
||||
</executiondata>
|
||||
|
||||
<structure name="JaCoCo Ant Example">
|
||||
<classfiles>
|
||||
<fileset dir="${build.dir}"/>
|
||||
</classfiles>
|
||||
<sourcefiles encoding="UTF-8">
|
||||
<fileset dir="${src.dir}"/>
|
||||
</sourcefiles>
|
||||
</structure>
|
||||
<check>
|
||||
<rule element="PACKAGE" includes="${coverage.check}">
|
||||
<limit counter="LINE" value="COVEREDRATIO" minimum="${min.coverage}"/>
|
||||
</rule>
|
||||
</check>
|
||||
</jacoco:report>
|
||||
<echo message="Coverage above ${min.coverage} in ${coverage.check}: OK" level="info"/>
|
||||
</target>
|
||||
|
||||
<target name="clean-doc">
|
||||
<delete dir="javadoc"/>
|
||||
</target>
|
||||
|
||||
<target name="generate-doc">
|
||||
<javadoc sourcepath="${src.dir}" destdir="${doc.dir}"
|
||||
private="true" use="true" author="true">
|
||||
<package name="cd"/>
|
||||
<package name="cd.frontend.semantic"/>
|
||||
<package name="cd.ir"/>
|
||||
<arg value="-notimestamp"/>
|
||||
</javadoc>
|
||||
</target>
|
||||
</project>
|
||||
|
|
|
|||
15
javali_tests/HW4/ErrDowncast.javali
Normal file
15
javali_tests/HW4/ErrDowncast.javali
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
/* Test illegal downcasts */
|
||||
|
||||
class A { }
|
||||
class B extends A { }
|
||||
|
||||
class Main {
|
||||
void main() {
|
||||
A a;
|
||||
B b;
|
||||
a = new A();
|
||||
b = (B) a; /* Should fail at runtime */
|
||||
write(0);
|
||||
writeln();
|
||||
}
|
||||
}
|
||||
23
javali_tests/HW4/FibonacciRecursive.javali
Normal file
23
javali_tests/HW4/FibonacciRecursive.javali
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
class Main {
|
||||
void main() {
|
||||
int a;
|
||||
a = fib(20);
|
||||
write(a);
|
||||
writeln();
|
||||
}
|
||||
|
||||
int fib(int n) {
|
||||
|
||||
int fib;
|
||||
int fib2;
|
||||
|
||||
if (n <= 1) {
|
||||
fib = n;
|
||||
} else {
|
||||
fib = fib(n-1);
|
||||
fib2 = fib(n-2);
|
||||
fib = fib + fib2;
|
||||
}
|
||||
return fib;
|
||||
}
|
||||
}
|
||||
14
javali_tests/HW4/OkArrayElementsMath.javali
Normal file
14
javali_tests/HW4/OkArrayElementsMath.javali
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
/* Test expressions using array elements as operands */
|
||||
class Main {
|
||||
int[] x;
|
||||
void main() {
|
||||
int i;
|
||||
x = new int[3];
|
||||
x[0] = 3;
|
||||
x[1] = 4;
|
||||
x[2] = 5;
|
||||
i = x[0] + x[1] + x[2];
|
||||
write(i);
|
||||
writeln();
|
||||
}
|
||||
}
|
||||
20
javali_tests/HW4/OkCallWithParamField.javali
Normal file
20
javali_tests/HW4/OkCallWithParamField.javali
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
/* Test access to parameters and fields */
|
||||
class A {
|
||||
int i;
|
||||
void foo(int p) {
|
||||
write(p);
|
||||
write(i);
|
||||
writeln();
|
||||
}
|
||||
}
|
||||
|
||||
class Main {
|
||||
void main() {
|
||||
A a;
|
||||
a = new A();
|
||||
a.i = 10;
|
||||
a.foo(1);
|
||||
a.foo(2);
|
||||
a.foo(3);
|
||||
}
|
||||
}
|
||||
28
javali_tests/HW4/OkDifferentReads.javali
Normal file
28
javali_tests/HW4/OkDifferentReads.javali
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
/* Test read() with different kinds of LHS values */
|
||||
class Main {
|
||||
int x;
|
||||
|
||||
void main() {
|
||||
int y;
|
||||
int[] arr;
|
||||
|
||||
write(1);
|
||||
writeln();
|
||||
|
||||
y = read();
|
||||
write(y + 1);
|
||||
writeln();
|
||||
|
||||
x = read();
|
||||
write(x + 1);
|
||||
writeln();
|
||||
|
||||
arr = new int[64];
|
||||
arr[x] = read();
|
||||
write(arr[x] + 1);
|
||||
writeln();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
4
javali_tests/HW4/OkDifferentReads.javali.in
Normal file
4
javali_tests/HW4/OkDifferentReads.javali.in
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
9
|
||||
51
|
||||
12
|
||||
|
||||
14
javali_tests/HW4/OkDowncast.javali
Normal file
14
javali_tests/HW4/OkDowncast.javali
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
/* Test legal downcasts */
|
||||
|
||||
class A { }
|
||||
class B extends A { }
|
||||
|
||||
class Main {
|
||||
void main() {
|
||||
A a;
|
||||
B b;
|
||||
a = new B();
|
||||
b = (B) a; /* OK at runtime */
|
||||
write(0);
|
||||
}
|
||||
}
|
||||
29
javali_tests/HW4/OkFieldInArray.javali
Normal file
29
javali_tests/HW4/OkFieldInArray.javali
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
/* Test access to fields from elements of arrays */
|
||||
class A {
|
||||
int field;
|
||||
void foo() {
|
||||
write(1);
|
||||
write(field);
|
||||
writeln();
|
||||
}
|
||||
}
|
||||
|
||||
class Main {
|
||||
A[] x;
|
||||
void main() {
|
||||
int i;
|
||||
x = new A[2];
|
||||
i = 1;
|
||||
write(i);
|
||||
writeln();
|
||||
|
||||
x[i] = new A();
|
||||
x[i].field = i + 1;
|
||||
|
||||
i = x[1].field;
|
||||
write(i);
|
||||
writeln();
|
||||
|
||||
x[1].foo();
|
||||
}
|
||||
}
|
||||
50
javali_tests/HW4/OkVirtualMethod.javali
Normal file
50
javali_tests/HW4/OkVirtualMethod.javali
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
/* Test virtual method calls */
|
||||
class A {
|
||||
void override() {
|
||||
write(0);
|
||||
writeln();
|
||||
}
|
||||
void base() {
|
||||
write(1);
|
||||
writeln();
|
||||
}
|
||||
}
|
||||
|
||||
class B extends A {
|
||||
void override() {
|
||||
write(2);
|
||||
writeln();
|
||||
}
|
||||
void sub() {
|
||||
write(3);
|
||||
writeln();
|
||||
}
|
||||
}
|
||||
|
||||
class Main {
|
||||
void main() {
|
||||
A a;
|
||||
B b;
|
||||
|
||||
a = null;
|
||||
b = null;
|
||||
|
||||
a = new A();
|
||||
a.base();
|
||||
a.override();
|
||||
|
||||
b = new B();
|
||||
b.base();
|
||||
b.override();
|
||||
b.sub();
|
||||
|
||||
a = b;
|
||||
a.base();
|
||||
a.override();
|
||||
|
||||
b.base();
|
||||
b.override();
|
||||
b.sub();
|
||||
|
||||
}
|
||||
}
|
||||
81
javali_tests/HW4/Quicksort.javali
Normal file
81
javali_tests/HW4/Quicksort.javali
Normal file
|
|
@ -0,0 +1,81 @@
|
|||
/* Overall test of arrays, loops, etc. that does a simple quicksort */
|
||||
|
||||
class Record {
|
||||
int a;
|
||||
void print() {
|
||||
write(a);
|
||||
writeln();
|
||||
}
|
||||
}
|
||||
|
||||
class Main {
|
||||
Record [] a;
|
||||
int i;
|
||||
|
||||
void swap(Record r1, Record r2) {
|
||||
int temp;
|
||||
|
||||
temp = r1.a;
|
||||
r1.a = r2.a;
|
||||
r2.a = temp;
|
||||
}
|
||||
|
||||
void sort(int left, int right) {
|
||||
int i,j;
|
||||
int m;
|
||||
|
||||
m = (a[left].a + a[right].a) / 2;
|
||||
i = left;
|
||||
j = right;
|
||||
while (i <= j) {
|
||||
while (a[i].a < m) { i = i+1; }
|
||||
while (a[j].a > m) { j = j-1; }
|
||||
if (i <= j) {
|
||||
swap(a[i], a[j]);
|
||||
i = i + 1;
|
||||
j = j - 1;
|
||||
}
|
||||
}
|
||||
if (left < j) { sort(left, j); }
|
||||
if (i < right) { sort(i, right); }
|
||||
}
|
||||
|
||||
void main() {
|
||||
|
||||
int SIZE;
|
||||
int j;
|
||||
|
||||
SIZE = 5;
|
||||
|
||||
a = new Record[SIZE];
|
||||
j = 0;
|
||||
while (j < SIZE) {
|
||||
a[j] = new Record();
|
||||
j = j + 1;
|
||||
}
|
||||
a[0].a = 5;
|
||||
a[1].a = 3;
|
||||
a[2].a = 1;
|
||||
a[3].a = 4;
|
||||
a[4].a = 2;
|
||||
|
||||
/* Numbers before sorting */
|
||||
j = 0;
|
||||
while (j < SIZE) {
|
||||
a[j].print();
|
||||
j = j + 1;
|
||||
}
|
||||
writeln();
|
||||
|
||||
sort(0, 4);
|
||||
|
||||
/* Numbers after sorting */
|
||||
j = 0;
|
||||
while (j < SIZE) {
|
||||
a[j].print();
|
||||
j = j + 1;
|
||||
}
|
||||
writeln();
|
||||
|
||||
}
|
||||
}
|
||||
12
javali_tests/HW4_nop90/Array/ErrArrayIndex.javali
Normal file
12
javali_tests/HW4_nop90/Array/ErrArrayIndex.javali
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
/* Test accessing arrays with invalid index*/
|
||||
class Main {
|
||||
void main() {
|
||||
int[] x;
|
||||
x = new int[5];
|
||||
x[0] = 3;
|
||||
x[1] = 4;
|
||||
x[2] = 5;
|
||||
|
||||
x[5] = 5; //this should fail
|
||||
}
|
||||
}
|
||||
9
javali_tests/HW4_nop90/Array/ErrArrayIndex2.javali
Normal file
9
javali_tests/HW4_nop90/Array/ErrArrayIndex2.javali
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
/* Test accessing arrays with invalid index*/
|
||||
class Main {
|
||||
void main() {
|
||||
int[] x;
|
||||
x = new int[5];
|
||||
|
||||
x[8] = 5; //this should fail
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue