blob: b7cc7afd58b86caa9b82342d69c65aab40d03d7f (
plain)
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
|
package no.eliashaugsbakk.kompilator.semanticAnalysis;
import static no.eliashaugsbakk.kompilator.tokenization.Keywords.KEYWORDS;
import no.eliashaugsbakk.kompilator.parsing.AST;
import no.eliashaugsbakk.kompilator.parsing.node.Program;
import no.eliashaugsbakk.kompilator.parsing.node.expression.Expression;
import no.eliashaugsbakk.kompilator.parsing.node.expression.FunctionCall;
import no.eliashaugsbakk.kompilator.parsing.node.expression.literal.StringLiteral;
import no.eliashaugsbakk.kompilator.parsing.node.statement.ExpressionStatement;
import no.eliashaugsbakk.kompilator.parsing.node.statement.Statement;
public class Analyzer {
private final AST ast;
public Analyzer(AST ast) {
this.ast = ast;
}
public void analyze() throws SemanticException {
Program program = (Program) ast.getRoot();
for (Statement stmt : program.statements) {
analyzeStatement(stmt);
}
}
private void analyzeStatement(Statement stmt) throws SemanticException {
if (stmt instanceof ExpressionStatement exprStmt) {
analyzeExpression(exprStmt.expression);
} else {
// Analyze the statement
// NO other statements implemented
}
}
private void analyzeExpression(Expression expr) throws SemanticException {
if (expr instanceof FunctionCall call) {
checkFunctionCall(call);
} else {
// analyze the expression
}
}
private void checkFunctionCall(FunctionCall call) throws SemanticException {
if (!KEYWORDS.contains(call.functionName)) {
throw new SemanticException("unknown function: " + call.functionName);
}
if (call.arguments.size() != 1) {
throw new SemanticException("print expects 1 argument, got " + call.arguments.size());
}
if (!(call.arguments.getFirst() instanceof StringLiteral)) {
throw new SemanticException("print expects String argument only");
}
}
}
|