1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
|
package ast.nodes;
import ast.types.*;
import java.util.ArrayList;
import semanticanalysis.SemanticError;
import semanticanalysis.SymbolTable;
/**
* Node for the `for_stmt` statement of the grammar.
*/
public class ForStmtNode implements Node {
private final Node exprList;
private final Node block;
public ForStmtNode(Node exprList, Node block) {
this.exprList = exprList;
this.block = block;
}
/**
* This methods check the semantics of the operation `for i in list: block`.
*
* After the `for` keyword, it's parsed as a list of expression. We verified
* that the last expression is always gonna be `expr comp_op expr`. We
* comp_op must be the `in` keyword. `i` could be of any lenght (e.g. `a, b,
* c`).
*
* In this function we define the following approch: we save in the
* SymbolTable every atom until the last expression in the expression's
* list. For the last element, we know that is in the `expr comp_op expr`
* format, so we take the left element and save it in the SymbolicTable as
* an atom.
*/
@Override
public ArrayList<SemanticError> checkSemantics(SymbolTable ST, int _nesting, FunctionType ft) {
ArrayList<SemanticError> errors = new ArrayList<>();
// Save every atom in the expression's list, except the last one
var l = (ExprListNode) exprList;
for (int i = 0; i < l.getSize() - 1; ++i) {
var e = (ExprNode) l.getElem(i);
ST.insert(e.getId(), e.typeCheck(), _nesting, "");
}
// Manage the last expression of expression's list
// Get the ExprNode
var left = (ExprNode) l.getElem(l.getSize() - 1);
// Get the left side expression of the operation, that
// corresponds to the first element of the expression list.
var atomLeft = (ExprNode) left.getExpr(0);
// ENHANCE: check that the comp_op is the `in` keyword
ST.insert(atomLeft.getId(), atomLeft.typeCheck(), _nesting, "");
errors.addAll(exprList.checkSemantics(ST, _nesting, ft));
errors.addAll(block.checkSemantics(ST, _nesting, ft));
return errors;
}
@Override
public Type typeCheck() {
return new VoidType();
}
/**
* We do not provide the cgen for the `for_stm` because we do not have the
* iterators idea that the real Python has.
*/
@Override
public String codeGeneration() {
return "";
}
@Override
public String toPrint(String prefix) {
return prefix + "For\n" + exprList.toPrint(prefix + " ") + block.toPrint(prefix + " ");
}
}
|