Skip to content

Commit cbd4a0e

Browse files
felixwellenandreasabel
authored andcommitted
Explain how to get started
1 parent 3cc91eb commit cbd4a0e

File tree

1 file changed

+50
-3
lines changed

1 file changed

+50
-3
lines changed

notes/java.md

+50-3
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ sealed interface TypedExpr {
7878

7979
# How to start
8080

81-
This is just one way to start and the ideas given are not complete - be prepared to change everything along the way to a solution that passes all tests. To get started, here is a possible first try at an implementaion of the `typecheck` function in the `TypeChecker`:
81+
This is just one way to start and the ideas given are not complete - be prepared to change everything along the way to a solution that passes all tests. To get started, here is a possible first try at an implementation of the `typecheck` function in the `TypeChecker`:
8282

8383
```java
8484
public AnnotatedProgram typecheck(Program p) {
@@ -91,7 +91,7 @@ This is just one way to start and the ideas given are not complete - be prepared
9191
}
9292
```
9393

94-
The first statement extracts a list of function definitions (from the parser) from `p` and stores it in `funDefs`. The `var` means that the type of `funDefs` is automatically infered. Then the signatures, which are stored in a field in the `TypeChecker` class, are initialized. To make the last line of this functions work, the type `AnnotatedProgram)` was modified to an inner `record` of the `TypeChecker` in the following way (the functions `extractSignatures` and `checkFunDefs` will be explained below):
94+
The first statement extracts a list of function definitions from (the parse-tree) `p` and stores it in `funDefs`. The `var` means that the type of `funDefs` is automatically infered. Then the signatures, which are stored in a field in the `TypeChecker` class, are initialized. To make the last line of this functions work, the type `AnnotatedProgram)` was modified to an inner `record` of the `TypeChecker` in the following way (the functions `extractSignatures` and `checkFunDefs` will be explained below):
9595

9696
```java
9797
record AnnotatedProgram(Map<String, TypedFunDef> defs) { }
@@ -109,12 +109,59 @@ The type `TypedFunDef` is also defined as an inner `record` of `TypeChecker`:
109109
```java
110110
sealed interface Statement {
111111
record Decl(String varName, CType type) implements Statement {}
112-
// TODO: add more cases
112+
// TODO: add more records for all the statements we need in the typed syntax
113113
}
114114
```
115115

116116
```java
117117
enum CType {
118118
Int, Double, Bool, Void
119119
}
120+
```
121+
122+
A `Type` from the parser syntax can then be translated to a `CType` like this (where this function definition could for example be put into `TypeChecker`):
123+
124+
```java
125+
CType typeFrom(Type type) {
126+
return switch(type) {
127+
case Type_int ignored -> CType.Int;
128+
// TODO: other cases
129+
default -> throw new IllegalStateException("Unexpected value: " + type);
130+
};
131+
}
132+
```
133+
134+
Now, we'll get back to the functions we left unexplained above, `extractSignatures` and `checkFunDefs`. As the name suggests, `extractSignatures` should pass through all function definitions and extract their signatures, which we will need to check the actual function defintions. This is a possible implementaion:
135+
136+
```java
137+
void extractSignatures(List<DFun> funDefs) {
138+
for(var def : funDefs) {
139+
List<CType> argTypes = def.listarg_.stream()
140+
.map(arg -> typeFrom(((ADecl) arg).type_))
141+
.toList();
142+
Signature signature = new Signature(typeFrom(def.type_), argTypes);
143+
if(signatures.put(def.id_, signature) != null) {
144+
throw new TypeException("Signature already defined for " + def.id_);
145+
};
146+
}
147+
}
148+
```
149+
150+
One thing that could be added here (or somewhere else) is, that there should be exactly one function called "main" which returns `int` and has no arguments. We will only give a sketch of an implementation of `checkFunDefs`. One thing to take care of is dealing with contexts in the right way, which needs some data structure like a stack or list. This is not explained in detail here:
151+
152+
```java
153+
HashMap<String, TypedFunDef> checkFunDefs(List<DFun> funDefs) {
154+
var checkedFunDefs = new HashMap<String, TypedFunDef>();
155+
for(var funDef : funDefs) {
156+
// TODO: produce 'args' which should be a list of argument names with their types
157+
// TODO: produce 'contexts' which should be some datastructure storing types of declared variables
158+
TypedFunDef checkedFunDef = new TypedFunDef(typeFrom(funDef.type_),
159+
args,
160+
checkStms(funDef.liststm_, contexts));
161+
if(checkedFunDefs.put(funDef.id_, checkedFunDef) != null) {
162+
throw new TypeException("Function " + funDef.id_ + " already defined!");
163+
}
164+
}
165+
return checkedFunDefs;
166+
120167
```

0 commit comments

Comments
 (0)